jcmd GC.heap_dump и full GC

Привет хлопцы

Занимаясь анализом утечки памяти (memory leak) в своем приложении у меня в голове сформировалось некоторое количество материала которым я бы хотел поделиться с вами в нескольких статьях. Сегодня речь пойдет про тулзу jcmd которая входит в поставку JDK и находится в каталоге bin

Для анализа утечки мне от коллег из девопса было предоставлено 3 хип дампа:

  1. «чистый» в момент поднятия приложения
  2. дамп под нагрузкой
  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 either key or key=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