SlideShare a Scribd company logo
© 2016 NetCracker Technology Corporation Confidential
Разбор сложных случаев OutOfMemoryError
Владимир Ситников
JEEConf 2016
2© 2016 NetCracker Technology Corporation Confidential
• Владимир Ситников
• Performance engineer @ NetCracker
• sitnikov@netcracker.com
• @VladimirSitnikv
Кто я
3© 2016 NetCracker Technology Corporation Confidential
О чём доклад
• Разбор некоторых out of memory: OS, JVM
• Примеры подходов к анализу/защите от OOM
• OpenJDK/OracleJDK
4© 2016 NetCracker Technology Corporation Confidential
Как понять, что память закончилась?
Видим в логах OutOfMemoryError – значит наш случай
• OutOfMemoryError: Java heap space
• OutOfMemoryError: heap allocation failed
• OutOfMemoryError: PermGen/Metadata space
• OutOfMemoryError: unable to create native thread
• ...
5© 2016 NetCracker Technology Corporation Confidential
Дело о потерянном процессе
• Java процесс работал и пропал
6© 2016 NetCracker Technology Corporation Confidential
Дело о потерянном процессе
• Java процесс работал и пропал
• hs_err файл не появился
7© 2016 NetCracker Technology Corporation Confidential
Дело о потерянном процессе
• Java процесс работал и пропал
• hs_err файл не появился
• В out, err, log пусто
8© 2016 NetCracker Technology Corporation Confidential
Дело о потерянном процессе
• Java процесс работал и пропал
• hs_err файл не появился
• В out, err, log пусто
• Как так?
9© 2016 NetCracker Technology Corporation Confidential
OOMkiller
У Linux память конечна, и если она
заканчивается, то может случиться разное:
• умрёт невезучий процесс (по умолчанию)
10© 2016 NetCracker Technology Corporation Confidential
OOMkiller
У Linux память конечна, и если она
заканчивается, то может случиться разное:
• умрёт невезучий процесс (по умолчанию)
• malloc вернёт ошибку «нет памяти»
11© 2016 NetCracker Technology Corporation Confidential
OOMkiller
У Linux память конечна, и если она
заканчивается, то может случиться разное:
• умрёт невезучий процесс (по умолчанию)
• malloc вернёт ошибку «нет памяти»
Ключевое слово в Linux: vm.overcommit_memory=0
12© 2016 NetCracker Technology Corporation Confidential
vm.overcommit_memory=0
vm.overcommit_memory=0
• Выглядит хорошо (не будет overcommit)
13© 2016 NetCracker Technology Corporation Confidential
vm.overcommit_memory=0
vm.overcommit_memory=0
• Выглядит хорошо (не будет overcommit)
• Работает не всегда: многие процессы выделяют,
но не используют память (~fork syscall)
14© 2016 NetCracker Technology Corporation Confidential
Смотрим потребление памяти
$ top
PID VIRT RES COMMAND
18133 9606m 7.3g ora_dbw0_DB11
32600 2163m 843m /jdk170_55/bin/java -Xmx200m
17532 1757m 602m /jdk160_14/bin/java -Xmx1024m
15© 2016 NetCracker Technology Corporation Confidential
Смотрим потребление памяти
$ top
PID VIRT RES COMMAND
18133 9606m 7.3g ora_dbw0_DB11
32600 2163m 843m /jdk170_55/bin/java -Xmx200m
17532 1757m 602m /jdk160_14/bin/java -Xmx1024m
$ free –g (http://www.linuxatemyram.com/)
total used free
Mem: 31 31 0
-/+ buffers/cache: 10 21
Swap: 8 3 5
Занимаемая память
Свободная
память
16© 2016 NetCracker Technology Corporation Confidential
Смотрим потребление памяти
$ top
PID VIRT RES COMMAND
18133 9606m 7.3g ora_dbw0_DB11
32600 2163m 843m /jdk170_55/bin/java -Xmx200m
17532 1757m 602m /jdk160_14/bin/java -Xmx1024m
17© 2016 NetCracker Technology Corporation Confidential
Следим за native памятью
• -XX:+NativeMemoryTracking=[off|summary|detail]
18© 2016 NetCracker Technology Corporation Confidential
Следим за native памятью
• -XX:+NativeMemoryTracking=[off|summary|detail]
• Работает начиная с 1.7u40
19© 2016 NetCracker Technology Corporation Confidential
Следим за native памятью
• -XX:+NativeMemoryTracking=[off|summary|detail]
• Работает начиная с 1.7u40
• Получить разбивку можно через
• jcmd <pid> VM.native_memory <output_file_name>
• -XX:+PrintNMTStatistics -XX:+UnlockDiagnosticVMOptions
• Или JMX: com.sun.management:type=
DiagnosticCommand/vmNativeMemory
20© 2016 NetCracker Technology Corporation Confidential
NMT на практике
21© 2016 NetCracker Technology Corporation Confidential
Ценный мех NMT
NMT позволяет
• более адресно заводить тикеты на OpenJDK
• проверять наличие утечек «служебной» памяти
Пример: GROOVY-7498 Groovy native memory leak
22© 2016 NetCracker Technology Corporation Confidential
Накладные расходы
• В 1.7u40 активация NMT замедляет на 5-10%
• http://hirt.se/blog/?p=401
• В 1.8u40 вошла доработка масштабируемости
NMT
• JEP 195: Scalable Native Memory Tracking
23© 2016 NetCracker Technology Corporation Confidential
Запускаем процесс
new ProcessBuilder("ping","123.321.123.321")
.start();
24© 2016 NetCracker Technology Corporation Confidential
Запускаем процесс
new ProcessBuilder("ping", "8.8.8.8")
.start();
25© 2016 NetCracker Technology Corporation Confidential
26© 2016 NetCracker Technology Corporation Confidential
На самом деле, можно
Если версия JDK свежая, то проблем нет:
• https://bugs.openjdk.java.net/browse/JDK-5049299
• 1.7u60+ всё ок
• 1.8u??+ (в 8u60 исправление есть наверняка)
27© 2016 NetCracker Technology Corporation Confidential
В предыдущих серияхверсиях
• ProcessBuilder#start() использует fork()
• -Xmx8g «по наследству» передаётся в ping
• В итоге ping либо не запустится, либо есть
шанс разбудить oomkiller
28© 2016 NetCracker Technology Corporation Confidential
Как запускать процессы в OpenJDK<1.7u60
• Либо вообще не запускать процессы
29© 2016 NetCracker Technology Corporation Confidential
Как запускать процессы в OpenJDK<1.7u60
• Либо вообще не запускать процессы
• Либо использовать jnr-posix (напрямую или из JRuby)
• https://github.com/jnr/jnr-posix
30© 2016 NetCracker Technology Corporation Confidential
OutOfMemoryError: unable to create native thread
• Кто виноват?
31© 2016 NetCracker Technology Corporation Confidential
OutOfMemoryError: unable to create native thread
• Кто виноват?
• 32bit JVM и в адресном пространстве уже негде выделить
место для стека (thread native stack)
32© 2016 NetCracker Technology Corporation Confidential
OutOfMemoryError: unable to create native thread
• Кто виноват?
• 32bit JVM и в адресном пространстве уже негде выделить
место для стека (thread native stack)
• Что делать?
• Переходить на 64bit JVM
33© 2016 NetCracker Technology Corporation Confidential
OutOfMemoryError: unable to create native thread
• Кто виноват?
• 32bit JVM и в адресном пространстве уже негде выделить
место для стека (thread native stack)
• Что делать?
• Переходить на 64bit JVM
• Или уменьшать -XX:ThreadStackSize, уменьшать -
XX:MaxPermSize
34© 2016 NetCracker Technology Corporation Confidential
А какая у нас версия?
$ java -Xmx800m -version
Error occurred during initialization of VM
java.lang.OutOfMemoryError: unable to create new
native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:714)
at java.lang.ref.Finalizer.<clinit>(Finalizer:226)
35© 2016 NetCracker Technology Corporation Confidential
limits
$ ulimit –a
36© 2016 NetCracker Technology Corporation Confidential
limits
$ ulimit –a
virtual memory (kbytes, -v) unlimited
37© 2016 NetCracker Technology Corporation Confidential
limits
$ ulimit –a
virtual memory (kbytes, -v) unlimited
open files (-n) 16384
38© 2016 NetCracker Technology Corporation Confidential
limits
$ ulimit –a
virtual memory (kbytes, -v) unlimited
open files (-n) 16384
max user processes (-u) 100000
39© 2016 NetCracker Technology Corporation Confidential
limits
$ ulimit –a
virtual memory (kbytes, -v) unlimited
open files (-n) 16384
max user processes (-u) 100000
stack size (kbytes, -s) 10240
40© 2016 NetCracker Technology Corporation Confidential
Действия в случае OutOfMemoryError
try {
"основной_монитор".notifyAll();
} catch (OutOfMemoryError e) {
log.info("Нужно больше памяти", e);
}
41© 2016 NetCracker Technology Corporation Confidential
Действия в случае OutOfMemoryError
try {
"основной_монитор".notifyAll();
} catch (OutOfMemoryError e) {
log.info("Нужно больше памяти", e);
}
42© 2016 NetCracker Technology Corporation Confidential
Реальные проблемы
• OOM может получить любой поток в любой
момент времени
43© 2016 NetCracker Technology Corporation Confidential
Реальные проблемы
• OOM может получить любой поток в любой
момент времени
• Например, ReentrantLock в момент unlock
44© 2016 NetCracker Technology Corporation Confidential
Реальные проблемы
• OOM может получить любой поток в любой
момент времени
• Например, ReentrantLock в момент unlock
• И мы получим вечнозанятую блокировку,
сломанную ArrayBlockingQueue, …
45© 2016 NetCracker Technology Corporation Confidential
Реальные проблемы
• OOM может получить любой поток в любой
момент времени
• Например, ReentrantLock в момент unlock
• И мы получим вечнозанятую блокировку,
сломанную ArrayBlockingQueue, …
• Аналогично и в случае StackOverflowError
46© 2016 NetCracker Technology Corporation Confidential
В случае аварии
В случае OutOfMemoryError/StackOverflowError
гораздо правильнее делать так:
• System.exit(146)
• -XX:OnError="kill -9 %p"
47© 2016 NetCracker Technology Corporation Confidential
Реальные проблемы
• Но как же ReentrantLock?
48© 2016 NetCracker Technology Corporation Confidential
Реальные проблемы
• Но как же ReentrantLock?
• JEP 270: Reserved Stack Areas for Critical Sections
доработка включена в JDK9
49© 2016 NetCracker Technology Corporation Confidential
В случае аварии
В случае OutOfMemoryError/StackOverflowError
гораздо правильнее
делать так:
• java 1.8u92+: JDK-8138745
-XX:+ExitOnOutOfMemory
-XX:+CrashOnOutOfMemory
50© 2016 NetCracker Technology Corporation Confidential
Java heap
• Хранит java объекты, их содержимое
51© 2016 NetCracker Technology Corporation Confidential
Java heap
• Хранит java объекты, их содержимое
• Очищается сборщиком мусора
52© 2016 NetCracker Technology Corporation Confidential
Java heap
• Хранит java объекты, их содержимое
• Очищается сборщиком мусора
• Бывает, заканчивается
53© 2016 NetCracker Technology Corporation Confidential
OutOfMemoryError: PermGen space
• Кто виноват?
• Размер PermGen слишком мал
• Загружено слишком много классов
54© 2016 NetCracker Technology Corporation Confidential
OutOfMemoryError: PermGen space
• Кто виноват?
• Размер PermGen слишком мал
• Загружено слишком много классов
• Что делать?
• Увеличивать perm gen: -XX:PermSize=512M -
XX:MaxPermSize=512M
• Искать лишние классы: jmap –histo
55© 2016 NetCracker Technology Corporation Confidential
OutOfMemoryError: PermGen space
• Кто виноват?
• Размер PermGen слишком мал
• Загружено слишком много классов
• Что делать?
• Увеличивать perm gen: -XX:PermSize=512M -
XX:MaxPermSize=512M
• Искать лишние классы: jmap –histo
• Обновлять java (в 8-ке будет ошибка Metadata space:)
56© 2016 NetCracker Technology Corporation Confidential
OutOfMemoryError: Java heap space
• Кто виноват?
• Выделено мало памяти
• Garbage Collector не успел собрать мусор
• Что делать?
• Выделять больше памяти: -Xms, -Xmx
• Анализировать использование памяти
57© 2016 NetCracker Technology Corporation Confidential
Как анализировать занятость heap
GC log фиксирует приход-расход памяти по времени
58© 2016 NetCracker Technology Corporation Confidential
Как анализировать занятость heap
GC log фиксирует приход-расход памяти по времени
• Как собрать: -Xloggc:logs/gc.log, -XX:+PrintGCDetails, и т.д.
59© 2016 NetCracker Technology Corporation Confidential
Как анализировать занятость heap
GC log фиксирует приход-расход памяти по времени
• Как собрать: -Xloggc:logs/gc.log, -XX:+PrintGCDetails, и т.д.
• Чем смотреть: GCViewer
60© 2016 NetCracker Technology Corporation Confidential
Как анализировать занятость heap
GC log фиксирует приход-расход памяти по времени
• Как собрать: -Xloggc:logs/gc.log, -XX:+PrintGCDetails, и т.д.
• Чем смотреть: GCViewer
• На что смотреть: «занятость памяти после full gc»
61© 2016 NetCracker Technology Corporation Confidential
GC лог здорового человека
• 60мс minor, 3sec major паузы
62© 2016 NetCracker Technology Corporation Confidential
GC лог здорового человека
• 60мс minor, 3sec major паузы
63© 2016 NetCracker Technology Corporation Confidential
GC лог здорового человека
• 60мс minor, 3sec major паузы
64© 2016 NetCracker Technology Corporation Confidential
GC лог курильщика
• Сплошные full gc
65© 2016 NetCracker Technology Corporation Confidential
GC лог курильщика
• Сплошные full gc
66© 2016 NetCracker Technology Corporation Confidential
Недоперепил
• Бывает, памяти остаётся мало
• GC постоянно как-то находит крохи мусора
67© 2016 NetCracker Technology Corporation Confidential
Недоперепил
• Бывает, памяти остаётся мало
• GC постоянно как-то находит крохи мусора
• А OutOfMemory всё нет и нет!
68© 2016 NetCracker Technology Corporation Confidential
Недоперепил
• Бывает, памяти остаётся мало
• GC постоянно как-то находит крохи мусора
• А OutOfMemory всё нет и нет!
• Что делать, шеф?
69© 2016 NetCracker Technology Corporation Confidential
Варианты действий, когда почти OOM
• Jmap – снимать дамп вручную
70© 2016 NetCracker Technology Corporation Confidential
Варианты действий, когда почти OOM
• Jmap – снимать дамп вручную
• GC overhead limit
71© 2016 NetCracker Technology Corporation Confidential
Варианты действий, когда почти OOM
• Jmap – снимать дамп вручную
• GC overhead limit
• -XX:GCHeapFreeLimit=20 (2 по умолчанию)
‒Если после full GC останется меньше X%, то OOM
72© 2016 NetCracker Technology Corporation Confidential
Варианты действий, когда почти OOM
• Jmap – снимать дамп вручную
• GC overhead limit
• -XX:GCHeapFreeLimit=20 (2 по умолчанию)
‒Если после full GC останется меньше X%, то OOM
• -XX:GCTimeLimit=Y (98 по умолчанию)
‒Если сборка мусора занимает более Y%
времени, то OOM
73© 2016 NetCracker Technology Corporation Confidential
Чисто там, где не мусорят
• Java Flight Recorder / Java Mission Control
74© 2016 NetCracker Technology Corporation Confidential
Как понять, кто создаёт объекты?
Java Flight Recorder
• Позволяет узнать stack trace где создавались объекты
• Позволяет узнать объём выделяемой памяти
75© 2016 NetCracker Technology Corporation Confidential
Как понять, кто создаёт объекты?
Java Flight Recorder
• Позволяет узнать stack trace где создавались объекты
• Позволяет узнать объём выделяемой памяти
• Бесплатно на test серверах
76© 2016 NetCracker Technology Corporation Confidential
Как понять, кто создаёт объекты?
Java Flight Recorder
• Позволяет узнать stack trace где создавались объекты
• Позволяет узнать объём выделяемой памяти
• Бесплатно на test серверах
Запуск:
• -XX:+UnlockCommercialFeatures -XX:+FlightRecorder
-XX:FlightRecorderOptions=repository=jfr,defaultrecording=false
77© 2016 NetCracker Technology Corporation Confidential
Как понять, кто создаёт объекты?
Java Flight Recorder
• Позволяет узнать stack trace где создавались объекты
• Позволяет узнать объём выделяемой памяти
• Бесплатно на test серверах
Запуск:
• -XX:+UnlockCommercialFeatures -XX:+FlightRecorder
-XX:FlightRecorderOptions=repository=jfr,defaultrecording=false
• jcmd <pid> JFR.start duration=2m filename=logs/myrecording.jfr
settings=profile stackdepth=2000
78© 2016 NetCracker Technology Corporation Confidential
OOM: heap space
Дамп памяти содержит снимок содержимого java heap
• Как собрать: -XX:HeapDumpOnOutOfMemoryError
79© 2016 NetCracker Technology Corporation Confidential
OOM: heap space
Дамп памяти содержит снимок содержимого java heap
• Как собрать: -XX:HeapDumpOnOutOfMemoryError
• jmap -dump
80© 2016 NetCracker Technology Corporation Confidential
OOM: heap space
Дамп памяти содержит снимок содержимого java heap
• Как собрать: -XX:HeapDumpOnOutOfMemoryError
• jmap -dump
• jmap -dump -F (force режим, если обычный не работает)
81© 2016 NetCracker Technology Corporation Confidential
OOM: heap space
Дамп памяти содержит снимок содержимого java heap
• Как собрать: -XX:HeapDumpOnOutOfMemoryError
• jmap -dump
• jmap -dump -F (force режим, если обычный не работает)
• Чем смотреть: Eclipse Memory Analyzer, VisualVM, jol, jvm-tools
82© 2016 NetCracker Technology Corporation Confidential
83© 2016 NetCracker Technology Corporation Confidential
Скорость работы jmap
$jmap –dump ..
real 0m7.992s
user 0m0.304s
sys 0m0.067s
$ jmap –dump –F ..
real 24m4.378s
user 21m56.321s
sys 6m51.676s
84© 2016 NetCracker Technology Corporation Confidential
В тяжёлых случаях
• core dump быстрее и надёжнее чем jmap -dump <pid>
$ ulimit –c
core file size (blocks, -c) 33’222’111
85© 2016 NetCracker Technology Corporation Confidential
В тяжёлых случаях
• core dump быстрее и надёжнее чем jmap -dump <pid>
$ ulimit –c
core file size (blocks, -c) 33’222’111
• Из core dump можно получить hprof (через jmap …)
86© 2016 NetCracker Technology Corporation Confidential
• Дамп памяти содержит данные всех объектов
• Состояние потоков (thread dump)
• Значения локальных переменных
Дампы памяти
87© 2016 NetCracker Technology Corporation Confidential
• Дамп памяти содержит данные всех объектов
• Состояние потоков (thread dump)
• Значения локальных переменных
Дампы памяти
Да, пароли там
тоже есть
88© 2016 NetCracker Technology Corporation Confidential
• -Xmx2G, OracleJDK 1.8u60
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid59998.hprof ...
Heap dump file created [1’650’484 bytes in 0.023 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap
space
at Demo1.main(Demo1.java:6)
Маловато будет
89© 2016 NetCracker Technology Corporation Confidential
• -Xmx2G, OracleJDK 1.8u60
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid59998.hprof ...
Heap dump file created [1’650’484 bytes in 0.023 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap
space
at Demo1.main(Demo1.java:6)
Маловато будет
long len = Runtime.getRuntime().maxMemory();
long[] array = new long[(int) len];  Demo1.java:6
90© 2016 NetCracker Technology Corporation Confidential
Терминология
«утекла память», «потребилась память»
== кто-то мешает GC её освободить
91© 2016 NetCracker Technology Corporation Confidential
Кто может держать память?
• Потоки (threads)
92© 2016 NetCracker Technology Corporation Confidential
Кто может держать память?
• Потоки (threads)
• Локальные переменные
93© 2016 NetCracker Technology Corporation Confidential
Кто может держать память?
• Потоки (threads)
• Локальные переменные
• Кишки JVM
94© 2016 NetCracker Technology Corporation Confidential
Кто может держать память?
• Потоки (threads)
• Локальные переменные
• Кишки JVM
• И далее по цепочкам простых ссылок,
WeakReferences, SoftReferences,
PhantomReferences
95© 2016 NetCracker Technology Corporation Confidential
Кто может держать память?
• Потоки (threads)
• Локальные переменные
• Кишки JVM
• И далее по цепочкам простых ссылок,
WeakReferences, SoftReferences,
PhantomReferences, FinalReferences
‾√
96© 2016 NetCracker Technology Corporation Confidential
‾√
WeakHashMap<K, V>
K1 V1
K2 V2
97© 2016 NetCracker Technology Corporation Confidential
‾√
WeakHashMap<K, V>
K1 V1
K2 V2
98© 2016 NetCracker Technology Corporation Confidential
‾√
WeakHashMap<K, V>
99© 2016 NetCracker Technology Corporation Confidential
WeakHashMap<K, V>
K1 V1
K2 V2
√‾
100© 2016 NetCracker Technology Corporation Confidential
WeakHashMap<K, V>
K1 V1
K2 V2
√‾
101© 2016 NetCracker Technology Corporation Confidential
И освободится ли WeakHashMap<K, V>?
K1 V1
K2 V2
?√‾
102© 2016 NetCracker Technology Corporation Confidential
√‾
Освобождению не подлежит
K1 V1
K2 V2
103© 2016 NetCracker Technology Corporation Confidential
√‾
Освобождению не подлежит
K1 V1
K2 V2
104© 2016 NetCracker Technology Corporation Confidential
√‾
Освобождению не подлежит
K1 V1
K2 V2
105© 2016 NetCracker Technology Corporation Confidential
√‾
Освобождению не подлежит
K1 V1
K2 V2
106© 2016 NetCracker Technology Corporation Confidential
√‾
Освобождению не подлежит
K1 V1
K2 V2
107© 2016 NetCracker Technology Corporation Confidential
√‾
Освобождению не подлежит
K1 V1
K2 V2
108© 2016 NetCracker Technology Corporation Confidential
√‾
Освобождению не подлежит
K1 V1
K2 V2
109© 2016 NetCracker Technology Corporation Confidential
И кто же так делает?
• XML element
• Элемент хранит ссылку на документ, а тот на всё
остальное
110© 2016 NetCracker Technology Corporation Confidential
И кто же так делает?
• XML element
• Элемент хранит ссылку на документ, а тот на всё
остальное
• java.beans.…
111© 2016 NetCracker Technology Corporation Confidential
Пример из жизни
•Запускаем Groovy
112© 2016 NetCracker Technology Corporation Confidential
Пример из жизни
•Запускаем Groovy
•Из JSR223 API (scripting API)
113© 2016 NetCracker Technology Corporation Confidential
Пример из жизни
•Запускаем Groovy
•Из JSR223 API (scripting API)
•И получаем OutOfMemoryError
114© 2016 NetCracker Technology Corporation Confidential
Терминология
Для любого объекта Ы есть 2 основных метрики
• Shallow heap – объём памяти, занимаемый самим
объектом
• Retained heap – объём памяти, который освободится,
если Ы окажется мусором
115© 2016 NetCracker Technology Corporation Confidential
Dominator tree
2 3
4 5
№2 не доминирует №3
№4 доминирует №5
√‾
116© 2016 NetCracker Technology Corporation Confidential
Groovy + Scripting for Java (JSR 223) = печаль (demo1)
Демо: groovy
117© 2016 NetCracker Technology Corporation Confidential
Dominator Tree (demo1)
• Показывает объекты, которые держат больше всего других
118© 2016 NetCracker Technology Corporation Confidential
Разбираем строку в число
* http://shipilev.net/blog/2014/exceptional-performance
static long toLongFast(char[] c)
throws IllegalArgumentException {
if (c.length == 1)
return c[0] - '0';
// Пусть с дробными разбираются другие
throw new IllegalArgumentException(); *
}
119© 2016 NetCracker Technology Corporation Confidential
Так быстрее, но не утечёт ли память?
static final IllegalArgumentException
CFE = new IllegalArgumentException();
static long toLongFast(char[] c)
throws IllegalArgumentException {
if (c.length == 1)
return c[0] - '0';
throw CFE;
120© 2016 NetCracker Technology Corporation Confidential
Throwable наносит ответный удар
• StackTraceElement это сплошные строки, но в
Throwable есть скрытое поле backtrace
121© 2016 NetCracker Technology Corporation Confidential
Throwable наносит ответный удар
• StackTraceElement это сплошные строки, но в
Throwable есть скрытое поле backtrace
• Оно прекрасно держит ссылки на классы из стектрейса
122© 2016 NetCracker Technology Corporation Confidential
Throwable наносит ответный удар
• StackTraceElement это сплошные строки, но в
Throwable есть скрытое поле backtrace
• Оно прекрасно держит ссылки на классы из стектрейса
• Иногда это может быть неожиданной ссылкой на класс
123© 2016 NetCracker Technology Corporation Confidential
Мораль
• Либо не используем «ControlFlowException»
• Либо не заполняем stacktrace
static final IllegalArgumentException
CFE = new IllegalArgumentException() {
public Throwable fillInStackTrace() {
return this;
}
}
124© 2016 NetCracker Technology Corporation Confidential
Object#finalize
Не стоит использовать finalizer’ы для «освобождения ресурсов»
• Finalizable объекты живут на 1 цикл GC (падают в old gen, ужас-
ужас)
125© 2016 NetCracker Technology Corporation Confidential
Object#finalize
Не стоит использовать finalizer’ы для «освобождения ресурсов»
• Finalizable объекты живут на 1 цикл GC (падают в old gen, ужас-
ужас)
• Невозможно объяснить JVM, что объект не надо
финализировать (если вручную вызвали .close)
126© 2016 NetCracker Technology Corporation Confidential
Object#finalize -> PhantomReference
PhantomReference позволяет организовать «автоматическое
освобождение ресурсов» с поддержкой ручного:
• PhantomReference сохраняется в какую-нибудь map/set
127© 2016 NetCracker Technology Corporation Confidential
Object#finalize -> PhantomReference
PhantomReference позволяет организовать «автоматическое
освобождение ресурсов» с поддержкой ручного:
• PhantomReference сохраняется в какую-нибудь map/set
• Если объект выходит из видимости, GC обрабатывает Phantom
128© 2016 NetCracker Technology Corporation Confidential
Object#finalize -> PhantomReference
PhantomReference позволяет организовать «автоматическое
освобождение ресурсов» с поддержкой ручного:
• PhantomReference сохраняется в какую-нибудь map/set
• Если объект выходит из видимости, GC обрабатывает Phantom
• Если пользователь закрыл объект вручную, то там же и
очищается Phantom
129© 2016 NetCracker Technology Corporation Confidential
PhantomReference
Map<Reference<Statement>, String> resources;
ReferenceQueue<Statement> queue = new ReferenceQueue<>();
public void autoCleanup() throws Throwable {
PreparedStatement ps = con.prepareStatement("select 1");
PhantomReference<Statement> ref = new PhantomReference<>(ps,
queue);
resources.put(ref, "name");
/* В методе .close(): */ ref.clear();
}
130© 2016 NetCracker Technology Corporation Confidential
На практике
• PostgreSQL JDBC драйвер pgjdbc использовал
Statement#finalize
• @Benchmark на «создание statement» падал с OOM
• После исключения finalize, стало 45ns/create даже
при 100% утекании (т.е. без ручных вызовов close):
https://github.com/pgjdbc/pgjdbc/pull/299
131© 2016 NetCracker Technology Corporation Confidential
• @shipilёv: не все хипдампы одинаково полезны
Eclipse Memory Analyzer
132© 2016 NetCracker Technology Corporation Confidential
Puzzler
++i--
Что это?
133© 2016 NetCracker Technology Corporation Confidential
Puzzler
++i--
^^^ оператор подёргивания
134© 2014 NetCracker Technology Corporation Confidential
Демо
135© 2016 NetCracker Technology Corporation Confidential
Dominator Tree
• Отображает то, сколько освободится, если удалить объект
136© 2016 NetCracker Technology Corporation Confidential
Dominator Tree (demo2)
• Quiz: Может ли объект дважды попасть в Dominator Tree?
137© 2016 NetCracker Technology Corporation Confidential
Основные окна Eclipse MAT (demo2)
• Class Histogram
• Показывает суммарную информацию по классам
138© 2016 NetCracker Technology Corporation Confidential
Dominator Tree (demo2)
• Как не погрязнуть в вечном разворачивании плюсиков?
139© 2016 NetCracker Technology Corporation Confidential
Алгоритм анализа дампов в Eclipse MAT
• Retained Set
• Immediate Dominators
140© 2016 NetCracker Technology Corporation Confidential
Алгоритм анализа дампов в Eclipse MAT
• Dominator Tree
• Retained Set
• Immediate Dominators
141© 2016 NetCracker Technology Corporation Confidential
Алгоритм анализа дампов в Eclipse MAT
• Dominator Tree
• Retained Set
• Immediate Dominators
• Retained Set
• Immediate Dominators
• Retained Set
• Immediate Dominators
142© 2016 NetCracker Technology Corporation Confidential
Dominator Tree
• “Show Retained Set” показывает плоский список удерживаемых
объектов
143© 2016 NetCracker Technology Corporation Confidential
Immediate dominators
• Кто-то очень любит HashMap$Entry. Как узнать кто?
• Immediate dominators!
144© 2016 NetCracker Technology Corporation Confidential
HashMap$Entry
• Если очень захотеть, то можно сделать Map с
накладными расходами в 4 байта на запись
145© 2016 NetCracker Technology Corporation Confidential
HashMap$Entry
• Если очень захотеть, то можно сделать Map с
накладными расходами в 4 байта на запись
• https://github.com/vlsi/compactmap
• См. v8/design.html#prop_access
146© 2016 NetCracker Technology Corporation Confidential
Но как же автоматизация?
• В Eclipse есть Object Query Language
147© 2016 NetCracker Technology Corporation Confidential
Но как же автоматизация?
• В Eclipse есть Object Query Language
• В простых случаях даже работает
148© 2016 NetCracker Technology Corporation Confidential
Но как же автоматизация?
• В Eclipse есть ограниченный :( Object Query Language
• Нет group by
• Нет join
• Нет distinct
149© 2016 NetCracker Technology Corporation Confidential
OQL!
• В Eclipse есть ограниченный :( Object Query Language
• Нет group by
• Нет join
• Нет distinct
• Может, оно и не нужно?
150© 2016 NetCracker Technology Corporation Confidential
Примеры, когда OQL пасует
• Если в одной коллекции хранятся разнородные
данные, то OQL не подходит
• EJB bean cache
• Свои кэши данных
• Если данные разбиты по разным java-объектам, то
OQL не подходит
151© 2016 NetCracker Technology Corporation Confidential
Ты ж программист
• Берём SQL engine: Apache Calcite
152© 2016 NetCracker Technology Corporation Confidential
Ты ж программист
• Берём SQL engine: Apache Calcite
• Прикручиваем его к MAT: mat-calcite-plugin
153© 2016 NetCracker Technology Corporation Confidential
Ты ж программист
• Берём SQL engine: Apache Calcite
• Прикручиваем его к MAT: mat-calcite-plugin
• Получаем:
• JOIN, WHERE, GROUP BY, ORDER BY, HAVING
• UNION, INTERSECT
• Подзапросы
• Аналитические функции (WINDOW, OVER)
154© 2016 NetCracker Technology Corporation Confidential
Пример SQL
-- Tables:
-- "java.lang.BigInteger" list of all BigIntegers
-- "instanceof java.lang.BigInteger" BigIntegers and all
select u."@THIS", s."@RETAINED"
from "java.lang.String" s
, "java.net.URL" u
where s."@THIS" = u.path
155© 2016 NetCracker Technology Corporation Confidential
Mat-calcite-plugin
• Плюсы:
• Хорошая поддержка SQL
• Ставится из MAT (“install new software…”)
156© 2016 NetCracker Technology Corporation Confidential
Mat-calcite-plugin
• Плюсы:
• Хорошая поддержка SQL
• Ставится из MAT (“install new software…”)
• Минусы:
• Подходит не для каждого запроса: Calcite заточен
под full scan
• Обход графа на SQL это та ещё радость
157© 2016 NetCracker Technology Corporation Confidential
VisualVM
• VisualVM UI работает неторопливо, но OQL позволяет
выполнять javascript map-reduce
• Распечатка System.properties:
select map(filter(heap.findClass('java.lang.System').props.table
, 'it != null && it.key != null && it.value != null')
, function (it) {
var res = it.key.toString() + ' = ' + it.value.toString();
return res; });
158© 2016 NetCracker Technology Corporation Confidential
aragozin/jvm-tools
• На очень больших дампах, dominator tree построить
невозможно
• В таких случаях поможет HeapPath из состава
aragozin/jvm-tools:
• field1.field2.field3.*.field4
• arrayField[0].arrayField2[*].field5
• hashMap?entrySet[key=name].value
159© 2016 NetCracker Technology Corporation Confidential
Ты ж java программист
• Java object layout хорошо подходит для анализа
индивидуальных объектов:
http://hg.openjdk.java.net/code-tools/jol/…/samples/
160© 2016 NetCracker Technology Corporation Confidential
Ты ж java программист
• Java object layout хорошо подходит для анализа
индивидуальных объектов:
http://hg.openjdk.java.net/code-tools/jol/…/samples/
• Плюсы:
• Управляется из java кода
• Выдаёт точные значения
161© 2016 NetCracker Technology Corporation Confidential
Ты ж java программист
• Java object layout хорошо подходит для анализа
индивидуальных объектов:
http://hg.openjdk.java.net/code-tools/jol/…/samples/
• Плюсы:
• Управляется из java кода
• Выдаёт точные значения
• Минусы:
• Управляется из java кода
162© 2016 NetCracker Technology Corporation Confidential
Выводы
• До OOM стараемся не доводить (-Xmx, thread pools)
• Если довели, то снимаем хипдамп (jmap, coredump)
• Обновляем JVM ради: исправления ошибок,
инструментария
163© 2016 NetCracker Technology Corporation Confidential
• Владимир Ситников
• Performance engineer @ NetCracker
• sitnikov@netcracker.com
• @VladimirSitnikv
Спасибо
Спасибо
164© 2015 NetCracker Technology Corporation Confidential

More Related Content

What's hot

Производительность open source решений
Производительность open source решенийПроизводительность open source решений
Производительность open source решений
Vladimir Sitnikov
 
Быстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоковБыстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоков
CodeFest
 
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Ontico
 
Организация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данныхОрганизация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данных
CodeFest
 
Deployment to production with an unexpected load
Deployment to production with an unexpected loadDeployment to production with an unexpected load
Deployment to production with an unexpected load
Grid Dynamics
 
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
Ontico
 
Реактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложенияРеактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложения
Matvey Malkov
 
Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»
DevDay
 
Kubernetes
KubernetesKubernetes
Kubernetes
SQALab
 
Selenium grid on-demand
Selenium grid on-demandSelenium grid on-demand
Selenium grid on-demand
SQALab
 
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и GrafanaВсевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
SQALab
 
Ядро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуруЯдро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуру
SQALab
 
10M tests per day
10M tests per day10M tests per day
10M tests per day
Sergey Grinev
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Dev2Dev
 
Zabbix и правильное обнаружение проблем - Алексей Владышев @ RootConf 2015
Zabbix и правильное обнаружение проблем - Алексей Владышев @ RootConf 2015Zabbix и правильное обнаружение проблем - Алексей Владышев @ RootConf 2015
Zabbix и правильное обнаружение проблем - Алексей Владышев @ RootConf 2015
Zabbix
 
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Fwdays
 
Threads & LinkedClone. Как сократить время на развертывание продукта и подгот...
Threads & LinkedClone. Как сократить время на развертывание продукта и подгот...Threads & LinkedClone. Как сократить время на развертывание продукта и подгот...
Threads & LinkedClone. Как сократить время на развертывание продукта и подгот...
SQALab
 
Service Discovery. More that it seems
Service Discovery. More that it seemsService Discovery. More that it seems
Service Discovery. More that it seems
Aleksandr Tarasov
 
Отладка производительности СУБД MySQL
Отладка производительности СУБД MySQLОтладка производительности СУБД MySQL
Отладка производительности СУБД MySQL
Sveta Smirnova
 
Автоматизированное тестирование - от сложного к простому, или Запускаем автот...
Автоматизированное тестирование - от сложного к простому, или Запускаем автот...Автоматизированное тестирование - от сложного к простому, или Запускаем автот...
Автоматизированное тестирование - от сложного к простому, или Запускаем автот...
SQALab
 

What's hot (20)

Производительность open source решений
Производительность open source решенийПроизводительность open source решений
Производительность open source решений
 
Быстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоковБыстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоков
 
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
 
Организация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данныхОрганизация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данных
 
Deployment to production with an unexpected load
Deployment to production with an unexpected loadDeployment to production with an unexpected load
Deployment to production with an unexpected load
 
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
 
Реактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложенияРеактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложения
 
Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»
 
Kubernetes
KubernetesKubernetes
Kubernetes
 
Selenium grid on-demand
Selenium grid on-demandSelenium grid on-demand
Selenium grid on-demand
 
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и GrafanaВсевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
 
Ядро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуруЯдро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуру
 
10M tests per day
10M tests per day10M tests per day
10M tests per day
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
 
Zabbix и правильное обнаружение проблем - Алексей Владышев @ RootConf 2015
Zabbix и правильное обнаружение проблем - Алексей Владышев @ RootConf 2015Zabbix и правильное обнаружение проблем - Алексей Владышев @ RootConf 2015
Zabbix и правильное обнаружение проблем - Алексей Владышев @ RootConf 2015
 
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
 
Threads & LinkedClone. Как сократить время на развертывание продукта и подгот...
Threads & LinkedClone. Как сократить время на развертывание продукта и подгот...Threads & LinkedClone. Как сократить время на развертывание продукта и подгот...
Threads & LinkedClone. Как сократить время на развертывание продукта и подгот...
 
Service Discovery. More that it seems
Service Discovery. More that it seemsService Discovery. More that it seems
Service Discovery. More that it seems
 
Отладка производительности СУБД MySQL
Отладка производительности СУБД MySQLОтладка производительности СУБД MySQL
Отладка производительности СУБД MySQL
 
Автоматизированное тестирование - от сложного к простому, или Запускаем автот...
Автоматизированное тестирование - от сложного к простому, или Запускаем автот...Автоматизированное тестирование - от сложного к простому, или Запускаем автот...
Автоматизированное тестирование - от сложного к простому, или Запускаем автот...
 

Viewers also liked

PostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performancePostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performance
Vladimir Sitnikov
 
Business environment in Azerbaijan.
Business environment in Azerbaijan.Business environment in Azerbaijan.
Business environment in Azerbaijan.
Fuad Ak
 
EY Azerbaijan. Business Guide Azerbaijan 2014
EY Azerbaijan. Business Guide Azerbaijan 2014EY Azerbaijan. Business Guide Azerbaijan 2014
EY Azerbaijan. Business Guide Azerbaijan 2014
Kanan Mammadli
 
Семантика final полей в java
Семантика final полей в javaСемантика final полей в java
Семантика final полей в java
Vladimir Sitnikov
 
High Performance Jdbc
High Performance JdbcHigh Performance Jdbc
High Performance Jdbc
Sam Pattsin
 
Final field semantics
Final field semanticsFinal field semantics
Final field semantics
Vladimir Sitnikov
 
JEEConf. Vanilla java
JEEConf. Vanilla javaJEEConf. Vanilla java
JEEConf. Vanilla java
Dmitriy Dumanskiy
 
Developing PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon RiggsDeveloping PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon Riggs
Fuenteovejuna
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
Anton Arhipov
 
Hibernate performance tuning
Hibernate performance tuningHibernate performance tuning
Hibernate performance tuning
Mikalai Alimenkou
 
Hibernate, how the magic is really done
Hibernate, how the magic is really doneHibernate, how the magic is really done
Hibernate, how the magic is really done
Mikalai Alimenkou
 

Viewers also liked (11)

PostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performancePostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performance
 
Business environment in Azerbaijan.
Business environment in Azerbaijan.Business environment in Azerbaijan.
Business environment in Azerbaijan.
 
EY Azerbaijan. Business Guide Azerbaijan 2014
EY Azerbaijan. Business Guide Azerbaijan 2014EY Azerbaijan. Business Guide Azerbaijan 2014
EY Azerbaijan. Business Guide Azerbaijan 2014
 
Семантика final полей в java
Семантика final полей в javaСемантика final полей в java
Семантика final полей в java
 
High Performance Jdbc
High Performance JdbcHigh Performance Jdbc
High Performance Jdbc
 
Final field semantics
Final field semanticsFinal field semantics
Final field semantics
 
JEEConf. Vanilla java
JEEConf. Vanilla javaJEEConf. Vanilla java
JEEConf. Vanilla java
 
Developing PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon RiggsDeveloping PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon Riggs
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
Hibernate performance tuning
Hibernate performance tuningHibernate performance tuning
Hibernate performance tuning
 
Hibernate, how the magic is really done
Hibernate, how the magic is really doneHibernate, how the magic is really done
Hibernate, how the magic is really done
 

Similar to A step-by-step approach toward high quality OutOfMemoryError analysis

Контейнеры в OpenStack: простое решение сложных проблем
Контейнеры в OpenStack: простое решение сложных проблемКонтейнеры в OpenStack: простое решение сложных проблем
Контейнеры в OpenStack: простое решение сложных проблем
OpenVZ
 
Контейнеры в OpenStack: простое решение сложных проблем
Контейнеры в OpenStack: простое решение сложных проблемКонтейнеры в OpenStack: простое решение сложных проблем
Контейнеры в OpenStack: простое решение сложных проблем
Yandex
 
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo Development
 
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Ontico
 
Другая виртуализация
Другая виртуализацияДругая виртуализация
Другая виртуализация
Yandex
 
Андрей Сибирёв "Ваше собственное облако — война за независимость"
Андрей Сибирёв "Ваше собственное облако — война за независимость"Андрей Сибирёв "Ваше собственное облако — война за независимость"
Андрей Сибирёв "Ваше собственное облако — война за независимость"
Yandex
 
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
Ontico
 
TMPA-2013 Sartakov: Genode
TMPA-2013 Sartakov: GenodeTMPA-2013 Sartakov: Genode
TMPA-2013 Sartakov: Genode
Iosif Itkin
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned
Alexander Syrotenko
 
Java Platform Performance BoF
Java Platform Performance BoFJava Platform Performance BoF
Java Platform Performance BoFDmitry Buzdin
 
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruБаба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
Yandex
 
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
IT Event
 
Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Unsafe: to be or to be removed?
Unsafe: to be or to be removed?
Alexey Fyodorov
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!
Roman Dvornov
 
Git in Sky presentation @ HighLoad++ 2013
Git in Sky presentation @ HighLoad++ 2013Git in Sky presentation @ HighLoad++ 2013
Git in Sky presentation @ HighLoad++ 2013Serguei Gitinsky
 
SmartOS/Solaris app tuning tools/technologies on HL++ 2013
SmartOS/Solaris app tuning tools/technologies on HL++ 2013SmartOS/Solaris app tuning tools/technologies on HL++ 2013
SmartOS/Solaris app tuning tools/technologies on HL++ 2013
Alex Chistyakov
 
Windbg: когда у нас не воспроизводится. Александр Головач ➠ CoreHard Autumn ...
Windbg: когда у нас не воспроизводится. Александр Головач ➠  CoreHard Autumn ...Windbg: когда у нас не воспроизводится. Александр Головач ➠  CoreHard Autumn ...
Windbg: когда у нас не воспроизводится. Александр Головач ➠ CoreHard Autumn ...
corehard_by
 
Построение мультисервисного стартапа в реалиях full-stack javascript
Построение мультисервисного стартапа в реалиях full-stack javascriptПостроение мультисервисного стартапа в реалиях full-stack javascript
Построение мультисервисного стартапа в реалиях full-stack javascript
FDConf
 
Build your own multistack JS startup
Build your own multistack JS startupBuild your own multistack JS startup
Build your own multistack JS startup
Артем Захарченко
 
Сергей Житинский, Александр Чистяков (Git in Sky)
Сергей Житинский, Александр Чистяков (Git in Sky)Сергей Житинский, Александр Чистяков (Git in Sky)
Сергей Житинский, Александр Чистяков (Git in Sky)
Ontico
 

Similar to A step-by-step approach toward high quality OutOfMemoryError analysis (20)

Контейнеры в OpenStack: простое решение сложных проблем
Контейнеры в OpenStack: простое решение сложных проблемКонтейнеры в OpenStack: простое решение сложных проблем
Контейнеры в OpenStack: простое решение сложных проблем
 
Контейнеры в OpenStack: простое решение сложных проблем
Контейнеры в OpenStack: простое решение сложных проблемКонтейнеры в OpenStack: простое решение сложных проблем
Контейнеры в OpenStack: простое решение сложных проблем
 
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
 
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
 
Другая виртуализация
Другая виртуализацияДругая виртуализация
Другая виртуализация
 
Андрей Сибирёв "Ваше собственное облако — война за независимость"
Андрей Сибирёв "Ваше собственное облако — война за независимость"Андрей Сибирёв "Ваше собственное облако — война за независимость"
Андрей Сибирёв "Ваше собственное облако — война за независимость"
 
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
 
TMPA-2013 Sartakov: Genode
TMPA-2013 Sartakov: GenodeTMPA-2013 Sartakov: Genode
TMPA-2013 Sartakov: Genode
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned
 
Java Platform Performance BoF
Java Platform Performance BoFJava Platform Performance BoF
Java Platform Performance BoF
 
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruБаба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
 
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
Roman Romanovsky, Sergey Rak - "JavaScript в IoT "
 
Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Unsafe: to be or to be removed?
Unsafe: to be or to be removed?
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!
 
Git in Sky presentation @ HighLoad++ 2013
Git in Sky presentation @ HighLoad++ 2013Git in Sky presentation @ HighLoad++ 2013
Git in Sky presentation @ HighLoad++ 2013
 
SmartOS/Solaris app tuning tools/technologies on HL++ 2013
SmartOS/Solaris app tuning tools/technologies on HL++ 2013SmartOS/Solaris app tuning tools/technologies on HL++ 2013
SmartOS/Solaris app tuning tools/technologies on HL++ 2013
 
Windbg: когда у нас не воспроизводится. Александр Головач ➠ CoreHard Autumn ...
Windbg: когда у нас не воспроизводится. Александр Головач ➠  CoreHard Autumn ...Windbg: когда у нас не воспроизводится. Александр Головач ➠  CoreHard Autumn ...
Windbg: когда у нас не воспроизводится. Александр Головач ➠ CoreHard Autumn ...
 
Построение мультисервисного стартапа в реалиях full-stack javascript
Построение мультисервисного стартапа в реалиях full-stack javascriptПостроение мультисервисного стартапа в реалиях full-stack javascript
Построение мультисервисного стартапа в реалиях full-stack javascript
 
Build your own multistack JS startup
Build your own multistack JS startupBuild your own multistack JS startup
Build your own multistack JS startup
 
Сергей Житинский, Александр Чистяков (Git in Sky)
Сергей Житинский, Александр Чистяков (Git in Sky)Сергей Житинский, Александр Чистяков (Git in Sky)
Сергей Житинский, Александр Чистяков (Git in Sky)
 

A step-by-step approach toward high quality OutOfMemoryError analysis

  • 1. © 2016 NetCracker Technology Corporation Confidential Разбор сложных случаев OutOfMemoryError Владимир Ситников JEEConf 2016
  • 2. 2© 2016 NetCracker Technology Corporation Confidential • Владимир Ситников • Performance engineer @ NetCracker • sitnikov@netcracker.com • @VladimirSitnikv Кто я
  • 3. 3© 2016 NetCracker Technology Corporation Confidential О чём доклад • Разбор некоторых out of memory: OS, JVM • Примеры подходов к анализу/защите от OOM • OpenJDK/OracleJDK
  • 4. 4© 2016 NetCracker Technology Corporation Confidential Как понять, что память закончилась? Видим в логах OutOfMemoryError – значит наш случай • OutOfMemoryError: Java heap space • OutOfMemoryError: heap allocation failed • OutOfMemoryError: PermGen/Metadata space • OutOfMemoryError: unable to create native thread • ...
  • 5. 5© 2016 NetCracker Technology Corporation Confidential Дело о потерянном процессе • Java процесс работал и пропал
  • 6. 6© 2016 NetCracker Technology Corporation Confidential Дело о потерянном процессе • Java процесс работал и пропал • hs_err файл не появился
  • 7. 7© 2016 NetCracker Technology Corporation Confidential Дело о потерянном процессе • Java процесс работал и пропал • hs_err файл не появился • В out, err, log пусто
  • 8. 8© 2016 NetCracker Technology Corporation Confidential Дело о потерянном процессе • Java процесс работал и пропал • hs_err файл не появился • В out, err, log пусто • Как так?
  • 9. 9© 2016 NetCracker Technology Corporation Confidential OOMkiller У Linux память конечна, и если она заканчивается, то может случиться разное: • умрёт невезучий процесс (по умолчанию)
  • 10. 10© 2016 NetCracker Technology Corporation Confidential OOMkiller У Linux память конечна, и если она заканчивается, то может случиться разное: • умрёт невезучий процесс (по умолчанию) • malloc вернёт ошибку «нет памяти»
  • 11. 11© 2016 NetCracker Technology Corporation Confidential OOMkiller У Linux память конечна, и если она заканчивается, то может случиться разное: • умрёт невезучий процесс (по умолчанию) • malloc вернёт ошибку «нет памяти» Ключевое слово в Linux: vm.overcommit_memory=0
  • 12. 12© 2016 NetCracker Technology Corporation Confidential vm.overcommit_memory=0 vm.overcommit_memory=0 • Выглядит хорошо (не будет overcommit)
  • 13. 13© 2016 NetCracker Technology Corporation Confidential vm.overcommit_memory=0 vm.overcommit_memory=0 • Выглядит хорошо (не будет overcommit) • Работает не всегда: многие процессы выделяют, но не используют память (~fork syscall)
  • 14. 14© 2016 NetCracker Technology Corporation Confidential Смотрим потребление памяти $ top PID VIRT RES COMMAND 18133 9606m 7.3g ora_dbw0_DB11 32600 2163m 843m /jdk170_55/bin/java -Xmx200m 17532 1757m 602m /jdk160_14/bin/java -Xmx1024m
  • 15. 15© 2016 NetCracker Technology Corporation Confidential Смотрим потребление памяти $ top PID VIRT RES COMMAND 18133 9606m 7.3g ora_dbw0_DB11 32600 2163m 843m /jdk170_55/bin/java -Xmx200m 17532 1757m 602m /jdk160_14/bin/java -Xmx1024m $ free –g (http://www.linuxatemyram.com/) total used free Mem: 31 31 0 -/+ buffers/cache: 10 21 Swap: 8 3 5 Занимаемая память Свободная память
  • 16. 16© 2016 NetCracker Technology Corporation Confidential Смотрим потребление памяти $ top PID VIRT RES COMMAND 18133 9606m 7.3g ora_dbw0_DB11 32600 2163m 843m /jdk170_55/bin/java -Xmx200m 17532 1757m 602m /jdk160_14/bin/java -Xmx1024m
  • 17. 17© 2016 NetCracker Technology Corporation Confidential Следим за native памятью • -XX:+NativeMemoryTracking=[off|summary|detail]
  • 18. 18© 2016 NetCracker Technology Corporation Confidential Следим за native памятью • -XX:+NativeMemoryTracking=[off|summary|detail] • Работает начиная с 1.7u40
  • 19. 19© 2016 NetCracker Technology Corporation Confidential Следим за native памятью • -XX:+NativeMemoryTracking=[off|summary|detail] • Работает начиная с 1.7u40 • Получить разбивку можно через • jcmd <pid> VM.native_memory <output_file_name> • -XX:+PrintNMTStatistics -XX:+UnlockDiagnosticVMOptions • Или JMX: com.sun.management:type= DiagnosticCommand/vmNativeMemory
  • 20. 20© 2016 NetCracker Technology Corporation Confidential NMT на практике
  • 21. 21© 2016 NetCracker Technology Corporation Confidential Ценный мех NMT NMT позволяет • более адресно заводить тикеты на OpenJDK • проверять наличие утечек «служебной» памяти Пример: GROOVY-7498 Groovy native memory leak
  • 22. 22© 2016 NetCracker Technology Corporation Confidential Накладные расходы • В 1.7u40 активация NMT замедляет на 5-10% • http://hirt.se/blog/?p=401 • В 1.8u40 вошла доработка масштабируемости NMT • JEP 195: Scalable Native Memory Tracking
  • 23. 23© 2016 NetCracker Technology Corporation Confidential Запускаем процесс new ProcessBuilder("ping","123.321.123.321") .start();
  • 24. 24© 2016 NetCracker Technology Corporation Confidential Запускаем процесс new ProcessBuilder("ping", "8.8.8.8") .start();
  • 25. 25© 2016 NetCracker Technology Corporation Confidential
  • 26. 26© 2016 NetCracker Technology Corporation Confidential На самом деле, можно Если версия JDK свежая, то проблем нет: • https://bugs.openjdk.java.net/browse/JDK-5049299 • 1.7u60+ всё ок • 1.8u??+ (в 8u60 исправление есть наверняка)
  • 27. 27© 2016 NetCracker Technology Corporation Confidential В предыдущих серияхверсиях • ProcessBuilder#start() использует fork() • -Xmx8g «по наследству» передаётся в ping • В итоге ping либо не запустится, либо есть шанс разбудить oomkiller
  • 28. 28© 2016 NetCracker Technology Corporation Confidential Как запускать процессы в OpenJDK<1.7u60 • Либо вообще не запускать процессы
  • 29. 29© 2016 NetCracker Technology Corporation Confidential Как запускать процессы в OpenJDK<1.7u60 • Либо вообще не запускать процессы • Либо использовать jnr-posix (напрямую или из JRuby) • https://github.com/jnr/jnr-posix
  • 30. 30© 2016 NetCracker Technology Corporation Confidential OutOfMemoryError: unable to create native thread • Кто виноват?
  • 31. 31© 2016 NetCracker Technology Corporation Confidential OutOfMemoryError: unable to create native thread • Кто виноват? • 32bit JVM и в адресном пространстве уже негде выделить место для стека (thread native stack)
  • 32. 32© 2016 NetCracker Technology Corporation Confidential OutOfMemoryError: unable to create native thread • Кто виноват? • 32bit JVM и в адресном пространстве уже негде выделить место для стека (thread native stack) • Что делать? • Переходить на 64bit JVM
  • 33. 33© 2016 NetCracker Technology Corporation Confidential OutOfMemoryError: unable to create native thread • Кто виноват? • 32bit JVM и в адресном пространстве уже негде выделить место для стека (thread native stack) • Что делать? • Переходить на 64bit JVM • Или уменьшать -XX:ThreadStackSize, уменьшать - XX:MaxPermSize
  • 34. 34© 2016 NetCracker Technology Corporation Confidential А какая у нас версия? $ java -Xmx800m -version Error occurred during initialization of VM java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:714) at java.lang.ref.Finalizer.<clinit>(Finalizer:226)
  • 35. 35© 2016 NetCracker Technology Corporation Confidential limits $ ulimit –a
  • 36. 36© 2016 NetCracker Technology Corporation Confidential limits $ ulimit –a virtual memory (kbytes, -v) unlimited
  • 37. 37© 2016 NetCracker Technology Corporation Confidential limits $ ulimit –a virtual memory (kbytes, -v) unlimited open files (-n) 16384
  • 38. 38© 2016 NetCracker Technology Corporation Confidential limits $ ulimit –a virtual memory (kbytes, -v) unlimited open files (-n) 16384 max user processes (-u) 100000
  • 39. 39© 2016 NetCracker Technology Corporation Confidential limits $ ulimit –a virtual memory (kbytes, -v) unlimited open files (-n) 16384 max user processes (-u) 100000 stack size (kbytes, -s) 10240
  • 40. 40© 2016 NetCracker Technology Corporation Confidential Действия в случае OutOfMemoryError try { "основной_монитор".notifyAll(); } catch (OutOfMemoryError e) { log.info("Нужно больше памяти", e); }
  • 41. 41© 2016 NetCracker Technology Corporation Confidential Действия в случае OutOfMemoryError try { "основной_монитор".notifyAll(); } catch (OutOfMemoryError e) { log.info("Нужно больше памяти", e); }
  • 42. 42© 2016 NetCracker Technology Corporation Confidential Реальные проблемы • OOM может получить любой поток в любой момент времени
  • 43. 43© 2016 NetCracker Technology Corporation Confidential Реальные проблемы • OOM может получить любой поток в любой момент времени • Например, ReentrantLock в момент unlock
  • 44. 44© 2016 NetCracker Technology Corporation Confidential Реальные проблемы • OOM может получить любой поток в любой момент времени • Например, ReentrantLock в момент unlock • И мы получим вечнозанятую блокировку, сломанную ArrayBlockingQueue, …
  • 45. 45© 2016 NetCracker Technology Corporation Confidential Реальные проблемы • OOM может получить любой поток в любой момент времени • Например, ReentrantLock в момент unlock • И мы получим вечнозанятую блокировку, сломанную ArrayBlockingQueue, … • Аналогично и в случае StackOverflowError
  • 46. 46© 2016 NetCracker Technology Corporation Confidential В случае аварии В случае OutOfMemoryError/StackOverflowError гораздо правильнее делать так: • System.exit(146) • -XX:OnError="kill -9 %p"
  • 47. 47© 2016 NetCracker Technology Corporation Confidential Реальные проблемы • Но как же ReentrantLock?
  • 48. 48© 2016 NetCracker Technology Corporation Confidential Реальные проблемы • Но как же ReentrantLock? • JEP 270: Reserved Stack Areas for Critical Sections доработка включена в JDK9
  • 49. 49© 2016 NetCracker Technology Corporation Confidential В случае аварии В случае OutOfMemoryError/StackOverflowError гораздо правильнее делать так: • java 1.8u92+: JDK-8138745 -XX:+ExitOnOutOfMemory -XX:+CrashOnOutOfMemory
  • 50. 50© 2016 NetCracker Technology Corporation Confidential Java heap • Хранит java объекты, их содержимое
  • 51. 51© 2016 NetCracker Technology Corporation Confidential Java heap • Хранит java объекты, их содержимое • Очищается сборщиком мусора
  • 52. 52© 2016 NetCracker Technology Corporation Confidential Java heap • Хранит java объекты, их содержимое • Очищается сборщиком мусора • Бывает, заканчивается
  • 53. 53© 2016 NetCracker Technology Corporation Confidential OutOfMemoryError: PermGen space • Кто виноват? • Размер PermGen слишком мал • Загружено слишком много классов
  • 54. 54© 2016 NetCracker Technology Corporation Confidential OutOfMemoryError: PermGen space • Кто виноват? • Размер PermGen слишком мал • Загружено слишком много классов • Что делать? • Увеличивать perm gen: -XX:PermSize=512M - XX:MaxPermSize=512M • Искать лишние классы: jmap –histo
  • 55. 55© 2016 NetCracker Technology Corporation Confidential OutOfMemoryError: PermGen space • Кто виноват? • Размер PermGen слишком мал • Загружено слишком много классов • Что делать? • Увеличивать perm gen: -XX:PermSize=512M - XX:MaxPermSize=512M • Искать лишние классы: jmap –histo • Обновлять java (в 8-ке будет ошибка Metadata space:)
  • 56. 56© 2016 NetCracker Technology Corporation Confidential OutOfMemoryError: Java heap space • Кто виноват? • Выделено мало памяти • Garbage Collector не успел собрать мусор • Что делать? • Выделять больше памяти: -Xms, -Xmx • Анализировать использование памяти
  • 57. 57© 2016 NetCracker Technology Corporation Confidential Как анализировать занятость heap GC log фиксирует приход-расход памяти по времени
  • 58. 58© 2016 NetCracker Technology Corporation Confidential Как анализировать занятость heap GC log фиксирует приход-расход памяти по времени • Как собрать: -Xloggc:logs/gc.log, -XX:+PrintGCDetails, и т.д.
  • 59. 59© 2016 NetCracker Technology Corporation Confidential Как анализировать занятость heap GC log фиксирует приход-расход памяти по времени • Как собрать: -Xloggc:logs/gc.log, -XX:+PrintGCDetails, и т.д. • Чем смотреть: GCViewer
  • 60. 60© 2016 NetCracker Technology Corporation Confidential Как анализировать занятость heap GC log фиксирует приход-расход памяти по времени • Как собрать: -Xloggc:logs/gc.log, -XX:+PrintGCDetails, и т.д. • Чем смотреть: GCViewer • На что смотреть: «занятость памяти после full gc»
  • 61. 61© 2016 NetCracker Technology Corporation Confidential GC лог здорового человека • 60мс minor, 3sec major паузы
  • 62. 62© 2016 NetCracker Technology Corporation Confidential GC лог здорового человека • 60мс minor, 3sec major паузы
  • 63. 63© 2016 NetCracker Technology Corporation Confidential GC лог здорового человека • 60мс minor, 3sec major паузы
  • 64. 64© 2016 NetCracker Technology Corporation Confidential GC лог курильщика • Сплошные full gc
  • 65. 65© 2016 NetCracker Technology Corporation Confidential GC лог курильщика • Сплошные full gc
  • 66. 66© 2016 NetCracker Technology Corporation Confidential Недоперепил • Бывает, памяти остаётся мало • GC постоянно как-то находит крохи мусора
  • 67. 67© 2016 NetCracker Technology Corporation Confidential Недоперепил • Бывает, памяти остаётся мало • GC постоянно как-то находит крохи мусора • А OutOfMemory всё нет и нет!
  • 68. 68© 2016 NetCracker Technology Corporation Confidential Недоперепил • Бывает, памяти остаётся мало • GC постоянно как-то находит крохи мусора • А OutOfMemory всё нет и нет! • Что делать, шеф?
  • 69. 69© 2016 NetCracker Technology Corporation Confidential Варианты действий, когда почти OOM • Jmap – снимать дамп вручную
  • 70. 70© 2016 NetCracker Technology Corporation Confidential Варианты действий, когда почти OOM • Jmap – снимать дамп вручную • GC overhead limit
  • 71. 71© 2016 NetCracker Technology Corporation Confidential Варианты действий, когда почти OOM • Jmap – снимать дамп вручную • GC overhead limit • -XX:GCHeapFreeLimit=20 (2 по умолчанию) ‒Если после full GC останется меньше X%, то OOM
  • 72. 72© 2016 NetCracker Technology Corporation Confidential Варианты действий, когда почти OOM • Jmap – снимать дамп вручную • GC overhead limit • -XX:GCHeapFreeLimit=20 (2 по умолчанию) ‒Если после full GC останется меньше X%, то OOM • -XX:GCTimeLimit=Y (98 по умолчанию) ‒Если сборка мусора занимает более Y% времени, то OOM
  • 73. 73© 2016 NetCracker Technology Corporation Confidential Чисто там, где не мусорят • Java Flight Recorder / Java Mission Control
  • 74. 74© 2016 NetCracker Technology Corporation Confidential Как понять, кто создаёт объекты? Java Flight Recorder • Позволяет узнать stack trace где создавались объекты • Позволяет узнать объём выделяемой памяти
  • 75. 75© 2016 NetCracker Technology Corporation Confidential Как понять, кто создаёт объекты? Java Flight Recorder • Позволяет узнать stack trace где создавались объекты • Позволяет узнать объём выделяемой памяти • Бесплатно на test серверах
  • 76. 76© 2016 NetCracker Technology Corporation Confidential Как понять, кто создаёт объекты? Java Flight Recorder • Позволяет узнать stack trace где создавались объекты • Позволяет узнать объём выделяемой памяти • Бесплатно на test серверах Запуск: • -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=repository=jfr,defaultrecording=false
  • 77. 77© 2016 NetCracker Technology Corporation Confidential Как понять, кто создаёт объекты? Java Flight Recorder • Позволяет узнать stack trace где создавались объекты • Позволяет узнать объём выделяемой памяти • Бесплатно на test серверах Запуск: • -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=repository=jfr,defaultrecording=false • jcmd <pid> JFR.start duration=2m filename=logs/myrecording.jfr settings=profile stackdepth=2000
  • 78. 78© 2016 NetCracker Technology Corporation Confidential OOM: heap space Дамп памяти содержит снимок содержимого java heap • Как собрать: -XX:HeapDumpOnOutOfMemoryError
  • 79. 79© 2016 NetCracker Technology Corporation Confidential OOM: heap space Дамп памяти содержит снимок содержимого java heap • Как собрать: -XX:HeapDumpOnOutOfMemoryError • jmap -dump
  • 80. 80© 2016 NetCracker Technology Corporation Confidential OOM: heap space Дамп памяти содержит снимок содержимого java heap • Как собрать: -XX:HeapDumpOnOutOfMemoryError • jmap -dump • jmap -dump -F (force режим, если обычный не работает)
  • 81. 81© 2016 NetCracker Technology Corporation Confidential OOM: heap space Дамп памяти содержит снимок содержимого java heap • Как собрать: -XX:HeapDumpOnOutOfMemoryError • jmap -dump • jmap -dump -F (force режим, если обычный не работает) • Чем смотреть: Eclipse Memory Analyzer, VisualVM, jol, jvm-tools
  • 82. 82© 2016 NetCracker Technology Corporation Confidential
  • 83. 83© 2016 NetCracker Technology Corporation Confidential Скорость работы jmap $jmap –dump .. real 0m7.992s user 0m0.304s sys 0m0.067s $ jmap –dump –F .. real 24m4.378s user 21m56.321s sys 6m51.676s
  • 84. 84© 2016 NetCracker Technology Corporation Confidential В тяжёлых случаях • core dump быстрее и надёжнее чем jmap -dump <pid> $ ulimit –c core file size (blocks, -c) 33’222’111
  • 85. 85© 2016 NetCracker Technology Corporation Confidential В тяжёлых случаях • core dump быстрее и надёжнее чем jmap -dump <pid> $ ulimit –c core file size (blocks, -c) 33’222’111 • Из core dump можно получить hprof (через jmap …)
  • 86. 86© 2016 NetCracker Technology Corporation Confidential • Дамп памяти содержит данные всех объектов • Состояние потоков (thread dump) • Значения локальных переменных Дампы памяти
  • 87. 87© 2016 NetCracker Technology Corporation Confidential • Дамп памяти содержит данные всех объектов • Состояние потоков (thread dump) • Значения локальных переменных Дампы памяти Да, пароли там тоже есть
  • 88. 88© 2016 NetCracker Technology Corporation Confidential • -Xmx2G, OracleJDK 1.8u60 java.lang.OutOfMemoryError: Java heap space Dumping heap to java_pid59998.hprof ... Heap dump file created [1’650’484 bytes in 0.023 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at Demo1.main(Demo1.java:6) Маловато будет
  • 89. 89© 2016 NetCracker Technology Corporation Confidential • -Xmx2G, OracleJDK 1.8u60 java.lang.OutOfMemoryError: Java heap space Dumping heap to java_pid59998.hprof ... Heap dump file created [1’650’484 bytes in 0.023 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at Demo1.main(Demo1.java:6) Маловато будет long len = Runtime.getRuntime().maxMemory(); long[] array = new long[(int) len];  Demo1.java:6
  • 90. 90© 2016 NetCracker Technology Corporation Confidential Терминология «утекла память», «потребилась память» == кто-то мешает GC её освободить
  • 91. 91© 2016 NetCracker Technology Corporation Confidential Кто может держать память? • Потоки (threads)
  • 92. 92© 2016 NetCracker Technology Corporation Confidential Кто может держать память? • Потоки (threads) • Локальные переменные
  • 93. 93© 2016 NetCracker Technology Corporation Confidential Кто может держать память? • Потоки (threads) • Локальные переменные • Кишки JVM
  • 94. 94© 2016 NetCracker Technology Corporation Confidential Кто может держать память? • Потоки (threads) • Локальные переменные • Кишки JVM • И далее по цепочкам простых ссылок, WeakReferences, SoftReferences, PhantomReferences
  • 95. 95© 2016 NetCracker Technology Corporation Confidential Кто может держать память? • Потоки (threads) • Локальные переменные • Кишки JVM • И далее по цепочкам простых ссылок, WeakReferences, SoftReferences, PhantomReferences, FinalReferences ‾√
  • 96. 96© 2016 NetCracker Technology Corporation Confidential ‾√ WeakHashMap<K, V> K1 V1 K2 V2
  • 97. 97© 2016 NetCracker Technology Corporation Confidential ‾√ WeakHashMap<K, V> K1 V1 K2 V2
  • 98. 98© 2016 NetCracker Technology Corporation Confidential ‾√ WeakHashMap<K, V>
  • 99. 99© 2016 NetCracker Technology Corporation Confidential WeakHashMap<K, V> K1 V1 K2 V2 √‾
  • 100. 100© 2016 NetCracker Technology Corporation Confidential WeakHashMap<K, V> K1 V1 K2 V2 √‾
  • 101. 101© 2016 NetCracker Technology Corporation Confidential И освободится ли WeakHashMap<K, V>? K1 V1 K2 V2 ?√‾
  • 102. 102© 2016 NetCracker Technology Corporation Confidential √‾ Освобождению не подлежит K1 V1 K2 V2
  • 103. 103© 2016 NetCracker Technology Corporation Confidential √‾ Освобождению не подлежит K1 V1 K2 V2
  • 104. 104© 2016 NetCracker Technology Corporation Confidential √‾ Освобождению не подлежит K1 V1 K2 V2
  • 105. 105© 2016 NetCracker Technology Corporation Confidential √‾ Освобождению не подлежит K1 V1 K2 V2
  • 106. 106© 2016 NetCracker Technology Corporation Confidential √‾ Освобождению не подлежит K1 V1 K2 V2
  • 107. 107© 2016 NetCracker Technology Corporation Confidential √‾ Освобождению не подлежит K1 V1 K2 V2
  • 108. 108© 2016 NetCracker Technology Corporation Confidential √‾ Освобождению не подлежит K1 V1 K2 V2
  • 109. 109© 2016 NetCracker Technology Corporation Confidential И кто же так делает? • XML element • Элемент хранит ссылку на документ, а тот на всё остальное
  • 110. 110© 2016 NetCracker Technology Corporation Confidential И кто же так делает? • XML element • Элемент хранит ссылку на документ, а тот на всё остальное • java.beans.…
  • 111. 111© 2016 NetCracker Technology Corporation Confidential Пример из жизни •Запускаем Groovy
  • 112. 112© 2016 NetCracker Technology Corporation Confidential Пример из жизни •Запускаем Groovy •Из JSR223 API (scripting API)
  • 113. 113© 2016 NetCracker Technology Corporation Confidential Пример из жизни •Запускаем Groovy •Из JSR223 API (scripting API) •И получаем OutOfMemoryError
  • 114. 114© 2016 NetCracker Technology Corporation Confidential Терминология Для любого объекта Ы есть 2 основных метрики • Shallow heap – объём памяти, занимаемый самим объектом • Retained heap – объём памяти, который освободится, если Ы окажется мусором
  • 115. 115© 2016 NetCracker Technology Corporation Confidential Dominator tree 2 3 4 5 №2 не доминирует №3 №4 доминирует №5 √‾
  • 116. 116© 2016 NetCracker Technology Corporation Confidential Groovy + Scripting for Java (JSR 223) = печаль (demo1) Демо: groovy
  • 117. 117© 2016 NetCracker Technology Corporation Confidential Dominator Tree (demo1) • Показывает объекты, которые держат больше всего других
  • 118. 118© 2016 NetCracker Technology Corporation Confidential Разбираем строку в число * http://shipilev.net/blog/2014/exceptional-performance static long toLongFast(char[] c) throws IllegalArgumentException { if (c.length == 1) return c[0] - '0'; // Пусть с дробными разбираются другие throw new IllegalArgumentException(); * }
  • 119. 119© 2016 NetCracker Technology Corporation Confidential Так быстрее, но не утечёт ли память? static final IllegalArgumentException CFE = new IllegalArgumentException(); static long toLongFast(char[] c) throws IllegalArgumentException { if (c.length == 1) return c[0] - '0'; throw CFE;
  • 120. 120© 2016 NetCracker Technology Corporation Confidential Throwable наносит ответный удар • StackTraceElement это сплошные строки, но в Throwable есть скрытое поле backtrace
  • 121. 121© 2016 NetCracker Technology Corporation Confidential Throwable наносит ответный удар • StackTraceElement это сплошные строки, но в Throwable есть скрытое поле backtrace • Оно прекрасно держит ссылки на классы из стектрейса
  • 122. 122© 2016 NetCracker Technology Corporation Confidential Throwable наносит ответный удар • StackTraceElement это сплошные строки, но в Throwable есть скрытое поле backtrace • Оно прекрасно держит ссылки на классы из стектрейса • Иногда это может быть неожиданной ссылкой на класс
  • 123. 123© 2016 NetCracker Technology Corporation Confidential Мораль • Либо не используем «ControlFlowException» • Либо не заполняем stacktrace static final IllegalArgumentException CFE = new IllegalArgumentException() { public Throwable fillInStackTrace() { return this; } }
  • 124. 124© 2016 NetCracker Technology Corporation Confidential Object#finalize Не стоит использовать finalizer’ы для «освобождения ресурсов» • Finalizable объекты живут на 1 цикл GC (падают в old gen, ужас- ужас)
  • 125. 125© 2016 NetCracker Technology Corporation Confidential Object#finalize Не стоит использовать finalizer’ы для «освобождения ресурсов» • Finalizable объекты живут на 1 цикл GC (падают в old gen, ужас- ужас) • Невозможно объяснить JVM, что объект не надо финализировать (если вручную вызвали .close)
  • 126. 126© 2016 NetCracker Technology Corporation Confidential Object#finalize -> PhantomReference PhantomReference позволяет организовать «автоматическое освобождение ресурсов» с поддержкой ручного: • PhantomReference сохраняется в какую-нибудь map/set
  • 127. 127© 2016 NetCracker Technology Corporation Confidential Object#finalize -> PhantomReference PhantomReference позволяет организовать «автоматическое освобождение ресурсов» с поддержкой ручного: • PhantomReference сохраняется в какую-нибудь map/set • Если объект выходит из видимости, GC обрабатывает Phantom
  • 128. 128© 2016 NetCracker Technology Corporation Confidential Object#finalize -> PhantomReference PhantomReference позволяет организовать «автоматическое освобождение ресурсов» с поддержкой ручного: • PhantomReference сохраняется в какую-нибудь map/set • Если объект выходит из видимости, GC обрабатывает Phantom • Если пользователь закрыл объект вручную, то там же и очищается Phantom
  • 129. 129© 2016 NetCracker Technology Corporation Confidential PhantomReference Map<Reference<Statement>, String> resources; ReferenceQueue<Statement> queue = new ReferenceQueue<>(); public void autoCleanup() throws Throwable { PreparedStatement ps = con.prepareStatement("select 1"); PhantomReference<Statement> ref = new PhantomReference<>(ps, queue); resources.put(ref, "name"); /* В методе .close(): */ ref.clear(); }
  • 130. 130© 2016 NetCracker Technology Corporation Confidential На практике • PostgreSQL JDBC драйвер pgjdbc использовал Statement#finalize • @Benchmark на «создание statement» падал с OOM • После исключения finalize, стало 45ns/create даже при 100% утекании (т.е. без ручных вызовов close): https://github.com/pgjdbc/pgjdbc/pull/299
  • 131. 131© 2016 NetCracker Technology Corporation Confidential • @shipilёv: не все хипдампы одинаково полезны Eclipse Memory Analyzer
  • 132. 132© 2016 NetCracker Technology Corporation Confidential Puzzler ++i-- Что это?
  • 133. 133© 2016 NetCracker Technology Corporation Confidential Puzzler ++i-- ^^^ оператор подёргивания
  • 134. 134© 2014 NetCracker Technology Corporation Confidential Демо
  • 135. 135© 2016 NetCracker Technology Corporation Confidential Dominator Tree • Отображает то, сколько освободится, если удалить объект
  • 136. 136© 2016 NetCracker Technology Corporation Confidential Dominator Tree (demo2) • Quiz: Может ли объект дважды попасть в Dominator Tree?
  • 137. 137© 2016 NetCracker Technology Corporation Confidential Основные окна Eclipse MAT (demo2) • Class Histogram • Показывает суммарную информацию по классам
  • 138. 138© 2016 NetCracker Technology Corporation Confidential Dominator Tree (demo2) • Как не погрязнуть в вечном разворачивании плюсиков?
  • 139. 139© 2016 NetCracker Technology Corporation Confidential Алгоритм анализа дампов в Eclipse MAT • Retained Set • Immediate Dominators
  • 140. 140© 2016 NetCracker Technology Corporation Confidential Алгоритм анализа дампов в Eclipse MAT • Dominator Tree • Retained Set • Immediate Dominators
  • 141. 141© 2016 NetCracker Technology Corporation Confidential Алгоритм анализа дампов в Eclipse MAT • Dominator Tree • Retained Set • Immediate Dominators • Retained Set • Immediate Dominators • Retained Set • Immediate Dominators
  • 142. 142© 2016 NetCracker Technology Corporation Confidential Dominator Tree • “Show Retained Set” показывает плоский список удерживаемых объектов
  • 143. 143© 2016 NetCracker Technology Corporation Confidential Immediate dominators • Кто-то очень любит HashMap$Entry. Как узнать кто? • Immediate dominators!
  • 144. 144© 2016 NetCracker Technology Corporation Confidential HashMap$Entry • Если очень захотеть, то можно сделать Map с накладными расходами в 4 байта на запись
  • 145. 145© 2016 NetCracker Technology Corporation Confidential HashMap$Entry • Если очень захотеть, то можно сделать Map с накладными расходами в 4 байта на запись • https://github.com/vlsi/compactmap • См. v8/design.html#prop_access
  • 146. 146© 2016 NetCracker Technology Corporation Confidential Но как же автоматизация? • В Eclipse есть Object Query Language
  • 147. 147© 2016 NetCracker Technology Corporation Confidential Но как же автоматизация? • В Eclipse есть Object Query Language • В простых случаях даже работает
  • 148. 148© 2016 NetCracker Technology Corporation Confidential Но как же автоматизация? • В Eclipse есть ограниченный :( Object Query Language • Нет group by • Нет join • Нет distinct
  • 149. 149© 2016 NetCracker Technology Corporation Confidential OQL! • В Eclipse есть ограниченный :( Object Query Language • Нет group by • Нет join • Нет distinct • Может, оно и не нужно?
  • 150. 150© 2016 NetCracker Technology Corporation Confidential Примеры, когда OQL пасует • Если в одной коллекции хранятся разнородные данные, то OQL не подходит • EJB bean cache • Свои кэши данных • Если данные разбиты по разным java-объектам, то OQL не подходит
  • 151. 151© 2016 NetCracker Technology Corporation Confidential Ты ж программист • Берём SQL engine: Apache Calcite
  • 152. 152© 2016 NetCracker Technology Corporation Confidential Ты ж программист • Берём SQL engine: Apache Calcite • Прикручиваем его к MAT: mat-calcite-plugin
  • 153. 153© 2016 NetCracker Technology Corporation Confidential Ты ж программист • Берём SQL engine: Apache Calcite • Прикручиваем его к MAT: mat-calcite-plugin • Получаем: • JOIN, WHERE, GROUP BY, ORDER BY, HAVING • UNION, INTERSECT • Подзапросы • Аналитические функции (WINDOW, OVER)
  • 154. 154© 2016 NetCracker Technology Corporation Confidential Пример SQL -- Tables: -- "java.lang.BigInteger" list of all BigIntegers -- "instanceof java.lang.BigInteger" BigIntegers and all select u."@THIS", s."@RETAINED" from "java.lang.String" s , "java.net.URL" u where s."@THIS" = u.path
  • 155. 155© 2016 NetCracker Technology Corporation Confidential Mat-calcite-plugin • Плюсы: • Хорошая поддержка SQL • Ставится из MAT (“install new software…”)
  • 156. 156© 2016 NetCracker Technology Corporation Confidential Mat-calcite-plugin • Плюсы: • Хорошая поддержка SQL • Ставится из MAT (“install new software…”) • Минусы: • Подходит не для каждого запроса: Calcite заточен под full scan • Обход графа на SQL это та ещё радость
  • 157. 157© 2016 NetCracker Technology Corporation Confidential VisualVM • VisualVM UI работает неторопливо, но OQL позволяет выполнять javascript map-reduce • Распечатка System.properties: select map(filter(heap.findClass('java.lang.System').props.table , 'it != null && it.key != null && it.value != null') , function (it) { var res = it.key.toString() + ' = ' + it.value.toString(); return res; });
  • 158. 158© 2016 NetCracker Technology Corporation Confidential aragozin/jvm-tools • На очень больших дампах, dominator tree построить невозможно • В таких случаях поможет HeapPath из состава aragozin/jvm-tools: • field1.field2.field3.*.field4 • arrayField[0].arrayField2[*].field5 • hashMap?entrySet[key=name].value
  • 159. 159© 2016 NetCracker Technology Corporation Confidential Ты ж java программист • Java object layout хорошо подходит для анализа индивидуальных объектов: http://hg.openjdk.java.net/code-tools/jol/…/samples/
  • 160. 160© 2016 NetCracker Technology Corporation Confidential Ты ж java программист • Java object layout хорошо подходит для анализа индивидуальных объектов: http://hg.openjdk.java.net/code-tools/jol/…/samples/ • Плюсы: • Управляется из java кода • Выдаёт точные значения
  • 161. 161© 2016 NetCracker Technology Corporation Confidential Ты ж java программист • Java object layout хорошо подходит для анализа индивидуальных объектов: http://hg.openjdk.java.net/code-tools/jol/…/samples/ • Плюсы: • Управляется из java кода • Выдаёт точные значения • Минусы: • Управляется из java кода
  • 162. 162© 2016 NetCracker Technology Corporation Confidential Выводы • До OOM стараемся не доводить (-Xmx, thread pools) • Если довели, то снимаем хипдамп (jmap, coredump) • Обновляем JVM ради: исправления ошибок, инструментария
  • 163. 163© 2016 NetCracker Technology Corporation Confidential • Владимир Ситников • Performance engineer @ NetCracker • sitnikov@netcracker.com • @VladimirSitnikv Спасибо
  • 164. Спасибо 164© 2015 NetCracker Technology Corporation Confidential