Сохраняет ли Java оптимизацию времени выполнения?

StackOverflow https://stackoverflow.com/questions/68109

  •  09-06-2019
  •  | 
  •  

Вопрос

Мой профессор провел неформальный тест на небольшой программе, и время Java было следующим:1,7 секунды для первого забега и 0,8 секунды для последующих заездов.

  • Связано ли это исключительно с загрузкой среды выполнения в операционную?

    ИЛИ

  • Влияет ли на это оптимизация кода Java и сохранение результатов этих оптимизаций (извините, я не знаю технического термина для этого)?

Это было полезно?

Решение

Я согласен, что разница в производительности, показанная на плакате, скорее всего, вызвана задержкой диска при переносе JRE в память.Компилятор Just In Time (JIT) не окажет влияния на производительность небольшого приложения.

Ява 1.6u10 (http://download.java.net/jdk6/) касается JAR-файлов времени выполнения в фоновом процессе (даже если Java не запущена), чтобы сохранить данные в дисковом кеше.Это значительно сокращает время запуска (что является огромным преимуществом для настольных приложений, но, вероятно, имеет незначительную ценность для серверных приложений).

В больших, долго работающих приложениях JIT имеет большое значение с течением времени, но количество времени, необходимое JIT для накопления достаточной статистики для запуска и оптимизации (5-10 секунд), очень и очень мало по сравнению с общим сроком службы. приложения (большинство из них работают месяцами и месяцами).Хотя сохранение и восстановление результатов JIT — интересное академическое упражнение, практическое улучшение не очень велико (именно поэтому команда JIT больше сосредоточилась на таких вещах, как стратегии GC для минимизации промахов в кэше памяти и т. д.).

Предварительная компиляция классов времени выполнения действительно немного помогает настольным приложениям (как и вышеупомянутая предварительная загрузка дискового кэша 6u10).

Другие советы

Ладно, я нашел, где это читал.Это все из «Изучения Java» (O'Reilly 2005):

Проблема традиционной JIT-компиляции заключается в том, что оптимизация кода требует времени.Таким образом, JIT-компилятор может давать достойные результаты, но может иметь значительную задержку при запуске приложения.Обычно это не проблема для долго работающих серверных приложений, но является серьезной проблемой для клиентского программного обеспечения и приложений, работающих на небольших устройствах с ограниченными возможностями.Чтобы решить эту проблему, технология компилятора Sun под названием HotSpot использует прием, называемый адаптивной компиляцией.Если посмотреть, на что на самом деле тратят свое время программы, то окажется, что они тратят почти все свое время на выполнение относительно небольшой части кода снова и снова.Кусок кода, который выполняется повторно, может составлять лишь небольшую часть всей программы, но его поведение определяет общую производительность программы.Адаптивная компиляция также позволяет среде выполнения Java использовать преимущества новых видов оптимизации, которые просто невозможно выполнить на статически скомпилированном языке, отсюда и утверждение, что код Java в некоторых случаях может работать быстрее, чем C/C++.

Чтобы воспользоваться этим фактом, HotSpot начинается как обычный интерпретатор байт-кода Java, но с отличием:он измеряет (профилирует) код во время его выполнения, чтобы увидеть, какие части выполняются повторно.Как только HotSpot узнает, какие части кода имеют решающее значение для производительности, он компилирует эти разделы в оптимальный машинный код.Поскольку он компилирует лишь небольшую часть программы в машинный код, он может позволить себе потратить время, необходимое на оптимизацию этих частей.Оставшуюся часть программы, возможно, вообще не нужно будет компилировать, а только интерпретировать, что позволит сэкономить память и время.Фактически, виртуальная машина Java по умолчанию от Sun может работать в одном из двух режимов:клиент и сервер, которые сообщают ему, следует ли делать упор на быстрый запуск и экономию памяти или на максимальную производительность.

В этот момент возникает естественный вопрос: зачем выбрасывать всю эту полезную информацию о профилировании каждый раз, когда приложение завершает работу?Что ж, Sun частично затронула эту тему с выпуском Java 5.0, используя общие классы, доступные только для чтения, которые постоянно хранятся в оптимизированной форме.Это значительно сокращает как время запуска, так и накладные расходы на выполнение многих приложений Java на данном компьютере.Технология выполнения этого сложна, но идея проста:оптимизируйте те части программы, которые должны выполняться быстро, и не беспокойтесь об остальном.

Мне интересно, как далеко продвинулась Sun со времен Java 5.0.

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

То, что вы видите, почти наверняка связано с кэшированием диска.

Я согласен, что это, скорее всего, результат кэширования диска.

К вашему сведению, виртуальная машина IBM Java 6 содержит опережающий компилятор (AOT).Код не так оптимизирован, как то, что мог бы создать JIT, но он хранится на всех виртуальных машинах, я полагаю, в какой-то постоянной общей памяти.Его основное преимущество — повышение производительности при запуске.Виртуальная машина IBM по умолчанию выполняет JIT-компиляцию метода после его вызова 1000 раз.Если он знает, что метод будет вызываться 1000 раз только во время запуска виртуальной машины (представьте себе часто используемый метод, такой как java.lang.String.equals(...) ), то ему будет полезно сохранить это в кеше AOT, чтобы ему никогда не приходилось тратить время на компиляцию во время выполнения.

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

Если вы включите время запуска JVM (которое полезно для сравнительного анализа взаимодействия с пользователем, но не очень полезно для оптимизации кода Java), то это может быть эффект кэширования файловой системы или это может быть вызвано функцией под названием «Общий доступ к данным класса Java»:

Для Солнца:

http://java.sun.com/j2se/1.5.0/docs/guide/vm/class-data-sharing.html

Это вариант, при котором JVM сохраняет подготовленный образ классов времени выполнения в файл, чтобы обеспечить более быструю загрузку (и совместное использование) их при следующем запуске.Вы можете управлять этим с помощью -Xshare:on или -Xshare:off с помощью Sun JVM.По умолчанию используется -Xshare:auto, который загружает образ общих классов, если он присутствует, а если его нет, он записывает его при первом запуске, если каталог доступен для записи.

С IBM Java 5 это, кстати, еще более мощно:

http://www.ibm.com/developerworks/java/library/j-ibmjava4/

Я не знаю ни одной распространенной JVM, которая сохраняла бы статистику JIT.

Java JVM (на самом деле может отличаться от разных реализаций JVM) при первом запуске будет интерпретировать байт-код.Как только он обнаруживает, что код будет выполняться достаточное количество раз, он JIT преобразуется в собственный машинный язык, чтобы он работал быстрее.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top