-
Notifications
You must be signed in to change notification settings - Fork 56
Core Java
Получение HEAP-дампа можно произвести как удалённо, используя VisualVM, либо через командную строку, зная PID приложения.
jmap -dump:format=b,file=dump.bin <javaProcessIdHere>
После получения дампа данный файл можно проанализировать либо в VisualVM, либо в Eclips Memory Analyzer Tool ( https://www.eclipse.org/mat/ ). Хотя бывает достаточно посмотреть содержимое дампа с помощью less, чтобы понять какие именно объекты занимают память.
Если дамп не удалось снять, то можно добавить опцию -F - force для снятия дампа.
Во время снятия дампа приложение будет остановлено. Процесс снятия дампа может быть длительным. Например, дампы размером в 1GB снимаются десятки минут.
На машине должен быть установлен GDB ( sudo apt-get install gdb )
Источник рецепта находится тут: gdb+jmap heap dump.
Кратко рецепт можно описать так:
$ sudo gdb --pid=16837
...
(gdb) gcore /tmp/jvm.core
Saved corefile /tmp/jvm.core
(gdb) detach
(gdb) quit
$ sudo jmap -dump:format=b,file=jvm.hprof /usr/bin/java /tmp/jvm.core
# Which will output...
Attaching to core /tmp/jvm.core from executable /usr/bin/java, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 23.5-b02
Dumping heap to jvm.hprof ...
...
Heap dump file created
Для удобства авторы рецепта приготовили shell-скрипт (скрипт есть статье или https://gist.github.com/wizardjedi/c1ab6a45615e443278e8) для автоматизации снятия дампов.
$ wget https://gist.githubusercontent.com/wizardjedi/c1ab6a45615e443278e8/raw/gdb-head-dump.sh
$ chmod +x gdb-head-dump.sh
$ ./gdb-head-dump.sh 57464
Приложение тоже "замораживается" на время снятие core-dump'а, но это время гораздо более короткое, чем с случае jmap. Core-dump в 1Gb делается менее секунды. Снятие heap dump'а занимает также много времени, но в данном случае приложение может работать. Так как снятие heap dump'а производится по core dump'у, то этот процесс можно проводить на другой машине.
В состав JVM входит утилита jhat, которая позволяет проводить анализ heap dump'а.
$ jhat dump.hprof
Reading from dump.hprof...
Dump file created Sun May 04 00:30:12 MSK 2014
Snapshot read, resolving...
Resolving 0 objects...
WARNING: hprof file does not include java.lang.Class!
WARNING: hprof file does not include java.lang.String!
WARNING: hprof file does not include java.lang.ClassLoader!
Chasing references, expect 0 dots
Eliminating duplicate references
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
На порту 7000 запускается web-интерфейс, с помощью которого можно проводить простой анализ heap dump'а.
$ jmap -heap 12582
Attaching to process ID 12582, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 23.7-b01
using thread-local object allocation.
Parallel GC with 18 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 2147483648 (2048.0MB)
NewSize = 1310720 (1.25MB)
MaxNewSize = 17592186044415 MB
OldSize = 5439488 (5.1875MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 21757952 (20.75MB)
MaxPermSize = 85983232 (82.0MB)
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 536870912 (512.0MB)
used = 209724968 (200.00931549072266MB)
free = 327145944 (311.99068450927734MB)
39.06431943178177% used
From Space:
capacity = 89456640 (85.3125MB)
used = 3735568 (3.5625152587890625MB)
free = 85721072 (81.74998474121094MB)
4.175842061584249% used
To Space:
capacity = 89456640 (85.3125MB)
used = 0 (0.0MB)
free = 89456640 (85.3125MB)
0.0% used
PS Old Generation
capacity = 1431699456 (1365.375MB)
used = 24576 (0.0234375MB)
free = 1431674880 (1365.3515625MB)
0.0017165613842351002% used
PS Perm Generation
capacity = 21757952 (20.75MB)
used = 13044608 (12.4403076171875MB)
free = 8713344 (8.3096923828125MB)
59.953289721385545% used
4464 interned Strings occupying 353472 bytes.
$ jmap -histo:live 12582
num #instances #bytes class name
----------------------------------------------
1: 24518 3343888 <methodKlass>
2: 24518 3291816 <constMethodKlass>
3: 2150 2255808 <constantPoolKlass>
4: 2150 1609872 <instanceKlassKlass>
5: 1889 1346912 <constantPoolCacheKlass>
6: 241 697712 [Ljava.util.concurrent.ConcurrentHashMap$HashEntry;
7: 7760 519112 [C
8: 3680 462440 [B
9: 107 395104 [Ljava.nio.channels.SelectionKey;
10: 2345 282400 java.lang.Class
11: 1392 277456 [Ljava.lang.Object;
12: 628 255096 <methodDataKlass>
13: 3101 191336 [S
14: 7646 183504 java.lang.String
15: 3366 177632 [[I
16: 1862 106904 [I
17: 178 102528 <objArrayKlassKlass>
18: 2842 90944 java.util.concurrent.ConcurrentHashMap$HashEntry
19: 623 50960 [Ljava.util.HashMap$Entry;
20: 1198 38336 java.util.HashMap$Entry
21: 2305 36880 java.lang.Object
22: 417 33360 java.lang.reflect.Method
23: 524 29344 java.util.HashMap
...
Total 111174 16353360
и
$ jmap -histo 12582
num #instances #bytes class name
----------------------------------------------
1: 1918 104024464 [I
2: 24518 3343888 <methodKlass>
3: 24518 3291816 <constMethodKlass>
4: 2150 2255808 <constantPoolKlass>
5: 2150 1609872 <instanceKlassKlass>
6: 1889 1346912 <constantPoolCacheKlass>
7: 263 870104 [Ljava.util.concurrent.ConcurrentHashMap$HashEntry;
8: 8706 608264 [C
9: 3905 486576 [B
10: 112 395264 [Ljava.nio.channels.SelectionKey;
11: 1502 298104 [Ljava.lang.Object;
12: 2345 282400 java.lang.Class
13: 628 255096 <methodDataKlass>
14: 8195 196680 java.lang.String
15: 3105 191656 [S
16: 3366 177632 [[I
17: 178 102528 <objArrayKlassKlass>
...
Total 120021 120826688
$ java -Xloggc:log/gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=128K -jar you_jar.jar
Задаёт вывод информации о GC в файл log/gc.log
. Выводиться полная информация о GC. Указываются даты и время GC. Файлы ротируются. Максимальное количество файлов 5, максимальный размер файла 128 Kb.
Существует проект консольной утилиты для JMX. jmxterm https://github.com/jiaqi/jmxterm.git http://wiki.cyclopsgroup.org/jmxterm
$ wget http://downloads.sourceforge.net/cyclops-group/jmxterm-1.0-alpha-4-uber.jar
$ java -jar jmxterm-1.0-alpha-4-uber.jar
Welcome to JMX terminal. Type "help" for available commands.
$>jvms
31453 ( ) - jmxterm-1.0-alpha-4-uber.jar
12582 ( ) - app1-1.1.jar
17522 ( ) - app2.jar
$>open 12582
#Connection to 12582 is opened
$>bean java.lang:type=Memory
#bean is set to java.lang:type=Memory
$>run gc
#calling operation gc of mbean java.lang:type=Memory
#operation returns:
null
$>quit
#bye
Однострочная команда
run -b java.lang:type=Memory gc | java -jar jmxterm-1.0-alpha-4-uber.jar -n -l host:port
Кроме того в состав JDK входит утилита JCMD:
jcmd <pid> GC.run
Взято с: http://stackoverflow.com/questions/3523837/how-do-you-force-garbage-collection-from-the-shell