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

Post on 07-Jan-2017

299 views 1 download

transcript

© 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 COMMAND18133 9606m 7.3g ora_dbw0_DB1132600 2163m 843m /jdk170_55/bin/java -Xmx200m17532 1757m 602m /jdk160_14/bin/java -Xmx1024m

15© 2016 NetCracker Technology Corporation Confidential

Смотрим потребление памяти

$ top PID VIRT RES COMMAND18133 9606m 7.3g ora_dbw0_DB1132600 2163m 843m /jdk170_55/bin/java -Xmx200m17532 1757m 602m /jdk160_14/bin/java -Xmx1024m$ free –g (http://www.linuxatemyram.com/) total used freeMem: 31 31 0-/+ buffers/cache: 10 21Swap: 8 3 5

Занимаемая память

Свободная память

16© 2016 NetCracker Technology Corporation Confidential

Смотрим потребление памяти

$ top PID VIRT RES COMMAND18133 9606m 7.3g ora_dbw0_DB1132600 2163m 843m /jdk170_55/bin/java -Xmx200m17532 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 -versionError occurred during initialization of VMjava.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 –avirtual memory (kbytes, -v) unlimited

37© 2016 NetCracker Technology Corporation Confidential

limits

$ ulimit –avirtual memory (kbytes, -v) unlimitedopen files (-n) 16384

38© 2016 NetCracker Technology Corporation Confidential

limits

$ ulimit –avirtual memory (kbytes, -v) unlimitedopen files (-n) 16384max user processes (-u) 100000

39© 2016 NetCracker Technology Corporation Confidential

limits

$ ulimit –avirtual memory (kbytes, -v) unlimitedopen files (-n) 16384max user processes (-u) 100000stack 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.992suser 0m0.304ssys 0m0.067s

$ jmap –dump –F ..real 24m4.378suser 21m56.321ssys 6m51.676s

84© 2016 NetCracker Technology Corporation Confidential

В тяжёлых случаях

• core dump быстрее и надёжнее чем jmap -dump <pid>$ ulimit –ccore file size (blocks, -c) 33’222’111

85© 2016 NetCracker Technology Corporation Confidential

В тяжёлых случаях

• core dump быстрее и надёжнее чем jmap -dump <pid>$ ulimit –ccore 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 spaceDumping 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 spaceDumping 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