2. Цели тренинга
Узнать некоторые подробности устройства JVM
вообще и HotSpot JVM в частности
Научиться писать код, который работает
быстрее
Узнать об утилитах для работы с JVM
2 www.ExigenServices.com
3. Содержание
Некоторые моменты архитектуры HotSpot
JVM
Эффективное взаимодействие с JIT-
компилятором
Эффективное взаимодействие со сборщиком
мусора
3 www.ExigenServices.com
5. Содержание
Архитектура HotSpot JVM
Эффективное взаимодействие с JIT-
компилятором
Эффективное взаимодействие со сборщиком
мусора
5 www.ExigenServices.com
6. Эффективное взаимодействие с JIT-
компилятором: типы компиляторов
client - 32bit
- простой, ориентирован на приложения клиентского типа
(апплеты, игры)
- работает быстро, важна скорость запуска приложений
- генерирует менее оптимальный код
server – 32bit, 64bit
- сложный, ориентирован на приложения серверного типа
- работает дольше, важна производительность создаваемого
кода
- более серьѐзный анализ, сбор большей статистики =>
применение более агрессивных оптимизаций
6 www.ExigenServices.com
7. Эффективное взаимодействие с JIT-
компилятором: типы компиляторов
Машины серверного класса:
Памяти ≥ 2Gb
Количество cpu ≥ 2
Компилятор, выбираемый по умолчанию
7 www.ExigenServices.com
8. Эффективное взаимодействие с JIT-
компилятором: типы компиляторов
Какой компилятор работает?
Используйте jinfo (Java SE 6)
Или вызовите
Или используйте java –version
Или просто поменяйте тип компилятора:
java –client MyClass.class
java –server MyClass.class
8 www.ExigenServices.com
9. Эффективное взаимодействие с JIT-
компилятором: escape-анализ
Escape-анализ
Является частью серверного компилятора
Использует понятие непокидающего объекта. Объект О
называется непокидающим для метода М, если:
- объявлен внутри метода M
- не является объектом класса Thread или производного от
него
- не имеет финализатора
- не сохраняется в статическом поле класса или в поле
покидающего объекта
- не передается другому методу в качестве аргумента, если
только достоверно не известно, что O не покидает и этот
метод
9 www.ExigenServices.com
10. Эффективное взаимодействие с JIT-
компилятором: escape-анализ
Объекты i1 и e1 являются непокидающими
10 www.ExigenServices.com
11. Эффективное взаимодействие с JIT-
компилятором: escape-анализ
Возможные оптимизации:
Устранение блокировок на непокидающих
объектах
Оптимизация ссылок на объекты
В ряде случаев – размещение объекта в
стеке или регистрах, а не в куче
11 www.ExigenServices.com
12. Эффективное взаимодействие с JIT-
компилятором: синхронизация
Синхронизация java-объектов
Операции захвата/освобождения объектов дорогие
В большинстве случаев захват объекта не является
состязательным:
- либо объект был свободным
- либо произошѐл рекурсивный захват в рамках потока
Решение:
Использование легковесных блокировок (эквивалентов CAS -
compare-and-swap – инструкций), это быстро
Использование тяжеловесных блокировок, если невозможно
использовать легковесные – это на порядок медленнее
12 www.ExigenServices.com
13. Эффективное взаимодействие с JIT-
компилятором: синхронизация
Использование CAS-инструкций может быть дорогим на
многопроцессорных машинах
Решение – привязанные (biased) блокировки
Минус – дорогая операция отката привязки. JVM
анализирует статистику откатов связывания и
может запретит привязывания блокировки для
определѐнных типов объектов
-XX: +UseBiasedLocking (начиная с 5.0 update 6)
13 www.ExigenServices.com
15. Эффективное взаимодействие с JIT-
компилятором
Советы по синхронизации:
Сразу рассчитывайте на использование вашего
кода в многопоточных приложениях.
Экономить на синхронизации нет смысла
Используйте средства обнаружения
состязательных блокировок (например, jvmstat)
15 www.ExigenServices.com
16. Содержание
Архитектура HotSpot JVM
Эффективное взаимодействие с JIT-
компилятором
Эффективное взаимодействие со
сборщиком мусора
16 www.ExigenServices.com
17. Эффективное взаимодействие со
сборщиком мусора: принципы работы
Сборка мусора (GC)
Размещает объекты в памяти, находит и освобождает место,
занимаемое ненужными объектами
Автоматическая и безопасная
Проще, если граф объектов «заморожен» (stop-the-world
паузы)
Возможны различные подходы
- С дефрагментацией или без
- Разные алгоритмы
- С разными типами аллокации (размещения объектов в
памяти) – например, учитывая «близость» области памяти к
процессору
17 www.ExigenServices.com
18. Эффективное взаимодействие со
сборщиком мусора: принципы работы
Сборка мусора с поколениями
Молодые и старые объекты содержатся отдельно
- В пространствах, называемых «поколениями»
- Возможны различные алгоритмы для молодого и старого
поколения
- Есть ещѐ третье пространство - Permanent Generation,
содержащее данные о загруженных классах,
откомпилированные методы и т.д.
Слабая гипотеза о поколениях
- Большинство объектов временные
- Молодое поколение можно собирать отдельно от старого
18 www.ExigenServices.com
19. Эффективное взаимодействие со
сборщиком мусора: принципы работы
Фоновая сборка мусора
– Уменьшает влияние GC на приложение
– Сборка мусора происходит одновременно с работой
приложения
– Если фоновый GC собирает только старшее поколение, нет
необходимости отслеживать изменения в молодом
поколении
19 www.ExigenServices.com
20. Эффективное взаимодействие со
сборщиком мусора: принципы работы
Последовательный / Serial GC
– Молодое поколение – последовательный копирующий GC,
старое – Mark-Sweep Compact
– Отлично подходит для клиентских приложений, не
требующих много памяти (≤ 200 Mb)
– “stop-the-world” сборщик – длительные паузы при больших
объѐмах
Фоновый / Concurrent Mark-Sweep GC
– Предназначен для избегания “stop-the-world” пауз
– Приводит к увеличению нагрузки на процессор, снижая
общую производительность
20 www.ExigenServices.com
23. Эффективное взаимодействие со
сборщиком мусора: аллокация
Быстрая аллокация
- Новый объект выделяется в молодом поколении
- Не нужно отслеживать изменение ссылок
- Гораздо быстрее, чем стандартные аллокаторы для С/С++
Быстрое освобождение новых объектов
- Сборка молодого поколения
Совет:
– Не бойтесь выделять маленькие объекты для
промежуточных результатов
– Избегайте бессмысленных аллокаций, они приводят к
лишним вызовам GC
23 www.ExigenServices.com
24. Эффективное взаимодействие со
сборщиком мусора: аллокация
Также не стоит забывать про анализ
локальности (escape analysis), поэтому:
Используйте неизменяемые маложивущие
объекты вместо часто изменяемых
долгоживущих объектов
Используйте простой код с большим
количеством аллокаций вместо сложных
контрукций с меньшим количеством
аллокаций
24 www.ExigenServices.com
25. Эффективное взаимодействие со
сборщиком мусора: аллокация
Большие объекты
- Долго аллоцировать (если объект не помещается в
молодом поколении)
- Дорого инициализировать
Частая аллокация и освобождение объектов разных
размеров приводит к фрагментации (для GC без
дефрагментации или с частичной дефрагментацией)
Поэтому избегайте использования больших объектов,
но не в ущерб удобству
25 www.ExigenServices.com
26. Эффективное взаимодействие со
сборщиком мусора: аллокация
Non-Uniform Memory Access (NUMA)
Доступ к памяти ассиметричен
– процессоры имеют разные задержки при доступе к различным участкам
памяти
- SPARC, Opteron, некоторые процессоры Intel
NUMA-аллокатор
- Память под объект выделяется «ближе» к процессору, на котором
выполняется аллоцирующий поток
- Доступ к объектам быстрее из потока, в котором произведена
аллокация
Включается явно: -XX: +UseNUMA
JDK6u2, для Solaris ≥ 9, в Linux (с Linux kernel 2.6.19 и glibc
2.6.1)
26 www.ExigenServices.com
27. Эффективное взаимодействие со
сборщиком мусора: аллокация
Обнуление ссылок
Редко помогает GC
- GC в состоянии определить, доступен ли объект
- Делает код менее читаемым
- Может породить скрытые ошибки
Исключения
- Структуры, основанные на массивах (в этом
случае мы сами управляет памятью)
- Предотвращение утечки памяти, связанной с
финализацией
27 www.ExigenServices.com
28. Эффективное взаимодействие со
сборщиком мусора: аллокация
Пулы объектов
Наследие старых VM с очень медленной скоростью аллокации
Необходимо помнить
- GC с поколениями оптимизированы для работы с
маложивущими неизменяемыми объектами
- Локальные объекты могут быть оптимизированы
Неиспользуемые объекты в пулах
- Лишняя работа для GC по сканированию/копированию
- Не приносит пользы, если приложение их не использует
28 www.ExigenServices.com
29. Эффективное взаимодействие со
сборщиком мусора: аллокация
Исключения
Объекты, которые дорого инициализировать
Объекты, которые связаны с редкими
ресурсами
- Потоки
- Соединение к БД
29 www.ExigenServices.com
30. Эффективное взаимодействие со
сборщиком мусора: аллокация
Излишняя аллокация
Правильная версия
Старайтесь реалистично оценивать размер структур данных
30 www.ExigenServices.com
31. Эффективное взаимодействие со
сборщиком мусора: System.gc()
Не используйте явных вызовов GC
- GC обладает информацией о скорости аллокации,
заполненности старшего поколения…
- System.gc() может повредить производительности
Исключения
- Вызов System.gc() в период явного бездействия
системы
В HotSpot
- System.gc() вызывает полный stop-the-world GC
- -XX: +DisableExplicitGC позволяет игнорировать
System.gc()
31 www.ExigenServices.com
32. Эффективное взаимодействие со
сборщиком мусора: финализация
Основное применение – освобождение
системных ресурсов
Финализируемые объекты – все с непустым
finalize()
Аллокация финализируемых объектов
- Существенно медленнее
- VM должна их отслеживать
32 www.ExigenServices.com
33. Эффективное взаимодействие со
сборщиком мусора: финализация
Использование финализации для управления
системными ресурсами
GC выполняет много работы по сопровождению
объекта с непустым finalize() и перед тем, как этот
объект будет финализирован
GC вызывается, когда заканчивается память
Памяти обычно больше, чем других системных
ресурсов
Поэтому управляйте ресурсами явно – используйте
пулы
33 www.ExigenServices.com
34. Эффективное взаимодействие со
сборщиком мусора: утечка памяти
Утечка памяти в системах со сборкой мусора
вызывается
– Объектами, которые доступны, но не
используются
– Использованием механизмов финализации
(временная утечка)
34 www.ExigenServices.com
35. Эффективное взаимодействие со
сборщиком мусора: утечка памяти
Стандартные случаи утечки памяти
Забытые обработчики событий в Swing, AWT и т.д.
Исключения могут менять порядок выполнения
35 www.ExigenServices.com
36. Эффективное взаимодействие со
сборщиком мусора: утечка памяти
Обнаружение утечек памяти
jconsole
jstat
VisualVM
jmap
-XX: PrintClassHistogram и Ctrl + Break
36 www.ExigenServices.com
37. Полезные ссылки
Список опций JVM
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-
140102.html
Этот тренинг подготовлен на основе доклада Екатерины
Павловой «Оптимизация производительности: эффективная
работа с виртуальной машиной»
http://conference.javatalks.ru/data/JVMTalk.pdf
Блоги по этим и многим другим вопросам
http://javablogs.com
37 www.ExigenServices.com