Рубрики
Без рубрики

Введение в JVM Внутренние

Автор оригинала: Graham Cox.

1. Введение

В этой статье мы узнаем, что такое внутренняя часть языка и как они работают на Java и других языках на основе JVM.

2. Что такое внутренняя часть?

внутренняя функция это функция, которая имеет специальную обработку компилятором или переводчиком для нашего языка программирования. В частности, это особый случай, когда компилятор или переводчик может заменить функцию альтернативной реализацией по разным причинам.

Язык программирования обычно обрабатывает это, понимая, что вызов конкретного метода является особенным, и всякий раз, когда мы называем этот метод, то полученное поведение отличается. Это позволяет нашему коду не отличаться от обычного, но реализация языка программирования может вмешаться в особых случаях, чтобы дать дополнительные преимущества.

Точный способ работы варьируется между языками программирования, а также между операционными системами и оборудованием. Однако, поскольку они обрабатываются для нас, мы, как правило, не нужно знать ни одной из этих деталей.

Внутренние могут дать различные преимущества. Замена определенных алгоритмов на родной код может заставить их работать лучше или даже использовать специфические функции операционной системы или базовое оборудование.

3. Внутренние данные о СПМ

JVM реализует внутренние возможности, заменяя точный вызов метода на точный класс альтернативной версией. JVM обрабатывает это сам, поэтому он будет работать только для основных классов и конкретных архитектур. Он также позволяет менять только определенные методы, а не целые классы.

Как именно это работает будет варьироваться между СПМ. Это включает в себя не только различные версии JVM – Java 8 против Java 11, например. Это также включает в себя различные цели JVM – Linux против Windows, например, – и особенно JVM поставщиков – Oracle против IBM. В некоторых случаях на них могут влиять определенные командно-линейные флаги, переданные СПМ.

Это разнообразие означает, что нет никакого способа определить, основываясь только на приложении, какие методы будут заменены на внутренние, а какие нет. Это будет отличаться на основе JVM работает приложение. Но это может привести к удивительным результатам в некоторых случаях – в том числе значительные преимущества производительности, достигнутые просто путем изменения JVM .

4. Преимущества производительности

Внутренние данные часто используются для реализации более эффективной версии одного и того же , например, за счет использования деталей реализации запущенной ОС или процессора. Иногда это связано с тем, что он может использовать более эффективную реализацию, а иногда он может пойти так далеко, как с помощью аппаратных конкретных функций.

Например, HotSpot JDK имеет внутреннюю реализацию для многих методов в java.lang.Math . В зависимости от точного JVM, они потенциально реализованы с использованием инструкций процессора, чтобы сделать точные расчеты, необходимые.

Простой тест продемонстрирует это. Возьмем, к примеру, java.lang.Math.sqrt () . Мы можем написать тест:

for (int a = 0; a < 100000; ++a) {
    double result = Math.sqrt(a);
}

Этот тест выполняет операцию квадратного корня 100 000 раз, что занимает около 123ms. Однако, если мы заменим этот код копией реализации Math.sqrt() вместо:

double result = StrictMath.sqrt(a);

Этот код делает то же самое, но выполняет в 166ms вместо. Это увеличение на 35% за счет копирования реализации вместо того, чтобы позволить JVM заменить его внутренней версией.

5. Невозможные реализации

В других случаях внутренняя часть используется для ситуаций, когда код не может быть реализован в Java. Они, как правило, зарезервированы для очень низкоуровневых случаев.

Например, давайте посмотрим на метод onSpinWait () в java.lang.Thread класс. Этот метод указывает на то, что этот поток в настоящее время не выполняет никакой работы и что время процессора может быть отдано другому потоку. Для реализации этого, он должен работать на самом низком уровне возможно.

HotSpot JDK для архитектур x86 реализует это непосредственно на процессоре, используя ПАУЗА код операции. Единственный другой способ достичь этого было бы использовать JNI вызов к родному коду, и накладные расходы, связанные с этим, в первую очередь победить преимущества вызова.

6. Выявление внутренних в Java

К сожалению, нет гарантированного способа определения методов, которые могут быть заменены внутренними версиями. Это потому, что различные СПМ или даже один и тот же JVM на разных платформах будет делать это для различных методов.

Тем не менее, при использовании Hotspot JVM по java 9, @HotSpotIntrinsicCandidate аннотация используется на всех методах, которые могут быть заменены. Добавление этой аннотации автоматически не приводит к замене метода. На самом деле, это происходит в рамках базового СПМ. Вместо этого разработчики JVM знают, что эти методы являются особенными и должны быть осторожны с ними.

Другие СПМ могут справиться с этим по-другому, если они вообще идентифицируются. Это включает в себя Hotspot JVM в Java 8 или старше.

7. Резюме

Мы не можем писать наши программы, чтобы полагаться на наличие внутренней части, потому что нет никакого способа узнать, если они будут доступны или нет на время выполнения JVM. Тем не менее, они являются убедительным подходом, который JVM может использовать для улучшения способа работы программ.

Эти внутренние могут быть – и часто – добавлены к новым версиям JVM. Таким образом, это позволяет улучшить наш уже работающий код, просто обновив JVM, на который мы работаем, так что это еще одна причина, чтобы гарантировать, что мы остаемся в курсе наших зависимостей и времени выполнения.