Привет хлопцы
Занимаясь анализом утечки памяти (memory leak) в своем приложении у меня в голове сформировалось некоторое количество материала которым я бы хотел поделиться с вами в нескольких статьях. Сегодня речь пойдет про тулзу jcmd которая входит в поставку JDK и находится в каталоге bin
Для анализа утечки мне от коллег из девопса было предоставлено 3 хип дампа:
- «чистый» в момент поднятия приложения
- дамп под нагрузкой
- дамп перед предполагаемым падением приложения по OutOfMemory
Все 3 дампа были примерно по 110Мб, что меня смутило сразу, т.к. дамп при старте и дамп под нагрузкой должен был как минимум отличаться объемом + меня смутили графики дампа в Eclipse Memory Analyzer, они выглядели идентично для всех трех дампов в разрезе созданных объектов. Все 3 хипа выглядели так, словно они сняты после работы GC
Пообщавшись с девопсами выяснилось, что снятие хипа они делали через рекомендуемую самим ораклом тулзу: jcmd GC.heap_dump
И уже почитав ынтырнет и офф.доку: https://docs.oracle.com/javase/9/tools/jcmd.htm#JSWOR743 я наткнулся на следующий кусок текста:
GC.heap_dump [options] [arguments]
Generates a HPROF format dump of the Java heap.
Impact: High — depends on the Java heap size and content. Request a full GC unless the-all
option is specified.
Permission:java.lang.management.ManagementPermission(monitor)
Note: The following
options
must be specified using eitherkey
orkey=value
syntax.-all
: [optional] Dump all objects, including unreachable objects (BOOLE AN, false)
Тут мы можем увидеть следующее: » Request a full GC unless the -all
option is specified «, т.е. наш GC.heap_dump запрашивает вызов полного GC если не передан ключ -all
А уже в самом ключе -all написано: «Dump all objects, including unreachable objects (BOOLE AN, false)«, дамп всех объектов, вместе с недостижимыми
Вывод:
Из чего я сделал вывод, что по дефолту, рекомендуемая тулза jcmd GC.heap_dump без ключа -all запрашивает вызов полного GC из-за чего снятые хипдампы теряют своей информативности
Для того чтобы снять дамб, воспользуйтесь следующей командой:
jcmd PID GC.heap_dump -all [path_dump_file]
ps, так же предоставляю вам сурсы этой тулзы, где в комментариях так же написано, что запрашивается вызов full GC: http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/ff3b27e6bcc2/src/share/vm/services/diagnosticCommand.cpp#l387