Настройка производительности JVM в действии: сделайте вашу идею IntelliJ идеально гладкой

Java задняя часть
Настройка производительности JVM в действии: сделайте вашу идею IntelliJ идеально гладкой

Эта статья включена в репозиторий Github.GitHub.com/silently952…

Публичный аккаунт WeChat: бета изучает Java

предисловие

Я составил статью об инструментах диагностики и обработки ошибок JVM.Учитывая, что большинство Java-программистов используют IntelliJ Idea, в этой статье используются инструменты для тренировки и настройки скорости работы IntelliJ Idea.

Состояние работы перед настройкой

Исходное содержимое конфигурации

Чтобы запросить путь к исходному файлу конфигурации, идею можно просмотреть в обзоре в VisualVM.

Исходное содержимое конфигурации:

-XX:ReservedCodeCacheSize=240m
-XX:+UseCompressedOops
-Dfile.encoding=UTF-8
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-Djdk.http.auth.tunneling.disabledSchemes=""
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow

-XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log
-XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof

-Xmx512m

Разработка плагина времени запуска печати

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

Время от времени запуска JVM до времени после завершения инициализации всех компонентов считается временем запуска IDEA.Код выглядит следующим образом

public class MyApplicationInitializedListener implements ApplicationInitializedListener {
    @Override
    public void componentsInitialized() {
        RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean();
        long startTime = bean.getStartTime();
        long costTime = System.currentTimeMillis() - startTime;

        Messages.showMessageDialog("毫秒:" + costTime, "启动耗时", Messages.getInformationIcon());
    }
}

Добавьте следующий код в plugin.xml:

<extensions defaultExtensionNs="com.intellij">
    <applicationInitializedListener id="MyApplicationInitializedListener"
                                    implementation="cn.silently9527.MyApplicationInitializedListener"/>
</extensions>

Информация о запуске и затраты времени до оптимизации

Согласно информации, собранной плагином запуска VisualGC и IDEA:

  • Запуск IDEA занимает 15 секунд
  • В общей сложности 22 сборки мусора заняли 1,2 с, в том числе 17 сборщиков мусора нового поколения, которые заняли 324 мс; 5 сборщиков мусора старого поколения, которые заняли 953 мс.
  • Загрузка 27526 классов заняла 21 секунду

По этим данным это нормально, а 15s на самом деле находится в допустимом диапазоне.Поскольку в этой статье в основном демонстрируется настройка производительности, необходимо протестировать, может ли она быть быстрее.

Начните пытаться оптимизировать

Настройка памяти для управления частотой сборки мусора

Из рисунка видно, что из 512 м памяти, заданных параметрами запуска, в новом поколении выделяется только 169 м. Так как IDEA является широко используемым инструментом для нашей разработки, обычный процесс компиляции также требует достаточно памяти, поэтому нам нужно сначала поставить общую память Чтобы расширить, здесь я ставлю максимальную память-Xmx1024m, чтобы JVM не нужно было тратить время на динамический расчет размера расширения во время GC, а также устанавливать-Xms1024m;

Всего в Eden в процессе запуска произошло 17 GC.Чтобы уменьшить количество GC в новом поколении, я установил размер памяти нового поколения на-Xmn256m;

Глядя на VisualGC после перезапуска, количество сборщиков мусора нового поколения сократилось с 17 до 7, а время, затрачиваемое на выполнение, сократилось с 324 мс до 152 мс.

До подгонки памяти было 5 полных сборщиков мусора, а после подгонки памяти оставалось еще 4 полных сборщика мусора, но из двух рисунков видно, что в старости еще много места осталось, и полный сборщик мусора должен не происходит; подумайте, нет ли где-нибудь в коде ручного вызоваSystem.gc()Полная сборка мусора запущена, поэтому параметры добавлены-XX:+DisableExplicitGC, снова перезапустить IDEA, результат очень неутешителен, осталось еще 4 Full GC;

Внимательно наблюдайте за графиком перед повторной оптимизацией и обратите внимание на Last Cause: Metadata GC Threshold. Последний GC — это GC, который должен произойти из-за нехватки памяти в области метапространства. Чтобы проверить наше предположение, распечатайте журнал GC в видеть. существуетidea.vmoptionsДобавьте параметры, связанные с журналом печати:

-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:../gc.log

Основные параметры журнала сборщика мусора JVM включают следующее:

  • -XX:+PrintGC выводить журнал GC
  • -XX:+PrintGCDetails выводить подробный журнал GC
  • -XX:+PrintGCTimeStamps Вывод временных меток GC (в виде базового времени)
  • -XX:+PrintGCDateStamps Распечатать метку времени сборщика мусора (в виде даты, например 2013-05-04T21:53:59.234+0800)
  • -XX:+PrintHeapAtGC Распечатать информацию о куче до и после GC
  • -Xloggc:../logs/gc.log Выходной путь к файлу журнала

Перезапустите идею и проверьте gc.log

вPSYoungGen:Указывает сборщик мусора ParallelScavenge, используемый новым поколением,31416K->0K(181248K)Указывает размер используемой памяти до gc -> объем используемой памяти после gc (общий размер памяти области)

Из журнала видно, что каждый полный сборщик мусора связан сMetadata GC Threshold, а Metaspace каждый раз почти не восстанавливает память, он просто расширяет вместимость этой области, легко найти причину и добавить следующие параметры для настройки размера Metaspace:

-XX:MetaspaceSize=256m

После повторного перезапуска Idea я обнаружил, что Full GC пропал, а настроение у меня было хорошее.

Тест открыл большой проект и щелкнул, чтобы скомпилировать код, и обнаружил, что моя идея застряла.После проверки VisualGC я обнаружил, что память кучи все еще свободна, и только метапространство было полностью занято, поэтому параметр максимального пространства я дал был слишком мал, поэтому я удалил его напрямую.-XX:MaxMetaspaceSize=256m

Выбор сборщика мусора

Только что из журнала gc мы видим, что по умолчанию используется сборщик мусора ParallelScavenge + Parallel Old. Эта комбинация ориентирована на пропускную способность. Здесь мы пытаемся перейти на сборщик мусора, который фокусируется на низкой задержке.

  • ParNew + CMS

существуетidea.vmoptionsДобавьте следующую конфигурацию в:

-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC

Просмотр VisualGC после перезапуска IDEA

Очень стыдно, один и тот же GC случился 6 раз,ParallelScavenge + Parallel OldКомбинация занимает 197 мс, в то время какParNew + CMSКомбинация занимает 379 мс, хотя это результат, но нужно учитывать, что на данный момент произошло только MinorGC, что будет, если произойдет результат FullGC, вы можете проверить это сами

  • G1

Мы пытаемся перейти на новейший сборщик мусора G1, вidea.vmoptionsДобавьте следующую конфигурацию в:

-XX:+UseG1GC

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

Оптимизация времени загрузки класса

Согласно предыдущему анализу, идея начала загружать 27526 классов, что заняло 21 с. Можем ли мы это оптимизировать? Поскольку идея является распространенным инструментом разработки и часто используется многими людьми, мы можем думать, что ее код безопасен, соответствует ли он требованиям текущей виртуальной машины и не будет угрожать безопасности виртуальной машины, поэтому мы используем параметр-Xverify:noneчтобы отключить процесс проверки байт-кода

перезапустить ИДЕЮ

Потребление времени сократилось до 11 секунд, а эффект все еще относительно очевиден.

Суммировать

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


Пишите до конца (обратите внимание, не потеряйтесь)

В тексте может быть больше или меньше недостатков и ошибок.Если у вас есть предложения или мнения, вы можете их комментировать и обмениваться.

Наконец,Проституция нехороша, творить нелегко, я надеюсь, что мои друзья могутНравится Комментарий ПодписатьсяСанлян, потому что это все источники мотивации, которыми я могу поделиться🙏


Я написал упрощенную версию springmvc с нуля и написал подробную документацию, чтобы помочь партнерам понять основные принципы springmvc. Друзья, которые в этом нуждаются, могут обратить внимание на общедоступный номер: бета-версия JAVA, ответ源码Просто