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

Однако что, если у меня есть ссылка на интерфейс, и интерфейс в настоящее время имеет только один реализатор, и этот реализатор является окончательным или метод является окончательным в этом реализаторе, может ли JVM выяснить это во время выполнения и оптимизировать эти вызовы?

10
Uri 10 Июн 2009 в 07:02

4 ответа

Лучший ответ

(Вставьте здесь цитату Кнута об оптимизации.)

См. главную страницу вики> Внутренние компоненты HotSpot для OpenJDK> Техники производительности.

  • Методы часто встроены. Это увеличивает "горизонт" компилятора оптимизация.
  • Статические, частные, окончательные и / или «специальные» вызовы легко встроенный.
  • Виртуальные (и интерфейсные) вызовы часто переводятся в "специальные" вызовы, если иерархия классов позволяет это. Зарегистрирована зависимость на случай, если дальнейшая загрузка класса испортится вещи.
  • Виртуальные (и интерфейсные) вызовы с однобоким профилем типа составлено с оптимистической проверкой пользу исторически распространенного типа (или двух типов).

Есть несколько интересных ссылок из Inlining.

11
Andreas 31 Дек 2016 в 18:39

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

-2
pmf 10 Июн 2009 в 03:27

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

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

У меня нет ссылки на статью об этом, но я прочитал ее несколько недель назад (и, возможно, это как раз в Java 7).

0
Daniel MigowskiDaniel Migowski 11 Июн 2009 в 20:23

AFAIK, JVM может встроить до двух методов, методы не должны быть окончательными. Он может это сделать, если методы небольшие и вызываются часто. Если ваш код вызывает три или более методов, будут вызываться только наиболее часто вызываемые методы.

Примечание 1: JVM заботится только о том, сколько существует реализаций, а только о том, сколько фактически вызывается.

Примечание 2: JVM может встроить методы, которые не существовали во время компиляции, имеет значение только код, доступный во время выполнения.

0
Peter Lawrey 11 Июн 2009 в 20:16