JDK에 포함된 jmap 명령으로 실행 중인 JVM의 heap 상태를 확인해보자.
먼저 실행중인 JVM의 프로세스 ID를 알아야 한다. JDK에 포함된 jps 명령을 사용하거나 "ps -ef | grep java"를 사용한다.
$ jps 14895 Bootstrap 20658 Jps |
JVM의 heap 상태를 확인할 때는 -heap 옵션을 사용한다.
$ jmap -heap 14895 Attaching to process ID 14895, please wait... Debugger attached successfully. Server compiler detected. JVM version is 20.2-b06 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 1073741824 (1024.0MB) NewSize = 1048576 (1.0MB) MaxNewSize = 4294901760 (4095.9375MB) OldSize = 4194304 (4.0MB) NewRatio = 2 SurvivorRatio = 8 PermSize = 16777216 (16.0MB) MaxPermSize = 268435456 (256.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 268500992 (256.0625MB) used = 4983224 (4.752372741699219MB) free = 263517768 (251.31012725830078MB) 1.8559424912664755% used From Space: capacity = 44695552 (42.625MB) used = 0 (0.0MB) free = 44695552 (42.625MB) 0.0% used To Space: capacity = 44695552 (42.625MB) used = 0 (0.0MB) free = 44695552 (42.625MB) 0.0% used PS Old Generation capacity = 715849728 (682.6875MB) used = 49058464 (46.785797119140625MB) free = 666791264 (635.9017028808594MB) 6.853179107445299% used PS Perm Generation capacity = 67895296 (64.75MB) used = 67656232 (64.52201080322266MB) free = 239064 (0.22798919677734375MB) 99.64789313239021% used |
Heap 설정과 각 Generation 별 사용 현황을 확인할 수 있다. 만약 Old Generation의 사용량이 지속적으로 증가한다면 memory leak을 의심할 수 있다.
이 때, -histo 옵션으로 클래스별 객체 수와 메모리 사용량을 확인할 수 있다.
$ jmap -histo:live 14895 | more num #instances #bytes class name ---------------------------------------------- 1: 146470 18465136 <constMethodKlass> 2: 146470 12896024 <methodKlass> 3: 136294 12627544 [C 4: 29162 8543584 [B 5: 13655 7868184 <constantPoolKlass> 6: 157523 7785024 <symbolKlass> 7: 13655 5912264 <instanceKlassKlass> 8: 10783 4518792 <constantPoolCacheKlass> 9: 136440 3274560 java.lang.String 10: 27292 2066056 [Ljava.util.HashMap$Entry; 11: 20292 1623360 java.lang.reflect.Method 12: 31501 1570240 [I 13: 14653 1406688 java.lang.Class 14: 23864 1336384 org.objectweb.asm.Label 15: 27767 1332816 org.objectweb.asm.Item 16: 39861 1275552 java.util.LinkedHashMap$Entry 17: 53115 1274760 org.objectweb.asm.Edge 18: 21894 1226064 org.objectweb.asm.Label 19: 25335 1216080 org.objectweb.asm.Item |
주기적으로 클래스별 객체 수와 메모리 사용량을 체크해보면 어느 클래스의 객체가 누수되고 있는지 쉽게 알 수 있다. 하지만, 어디에서 누수를 일으키는지는 jmap 만으로는 알 수 없고, heap dump를 떠서 분석해야 알 수 있다.
이제 -dump 옵션으로 heap dump를 뜬 후, MAT 등으로 분석한다.
$jmap -dump:format=b,file=heap.14895.hprof 14895 |
[출처] jmap으로 JVM heap 상태 확인|작성자 소프