jmap命令 檢查內存泄漏


命令介紹

jmap - Prints shared object memory maps or heap memory details for a process, core file, or remote
debug server.

jmap不僅能生成dump文件,還闊以查詢finalize執行隊列、Java堆和永久代的詳細信息,如當前使用率、當前使用的是哪種收集器等。主要的作用是檢查內存泄漏、對象創建不合理和銷毀等問題

語法: 

jmap [ options ] pid

jmap [ options ] executable core

jmap [ options ] [ pid ] server-id@ ] remote-hostname-or-IP

 

常用選項

-dump:[live,] format=b, file=<filename> <pid>

dump堆使用信息到文件,format指定格式,live指存活的對象,file為文件名

[root@node1 ~]# jmap -dump:live,format=b,file=hprof.dump 2712
2712: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding 報錯原因: jvm運行時會生成一個目錄hsperfdata_$USER($USER是啟動java進程的用戶),在linux中默認是/tmp。目錄下會有些pid文件,存放jvm進程信息。
jvm相關命令會從這個路徑/tmp/hsperfdata_$USER去獲取pid的連接信息,我是root用戶執行的命令,所以沒有pid文件,而對應應用程序里面有

例如:

 

 

 

 jmap報錯原因:

可能是由於tmpwatch機制,防止/tmp目錄里文件過多,系統每天基於此機制刪除超過240小時未訪問的文件和目錄。

 jmap和jstack不能正常運行的原因:

因為對應目錄里沒有pid文件

  查看關鍵配置/etc/cron.daily/tmpwatch:   flags=-umc /usr/sbin/tmpwatch "$flags"   -x /tmp/.X11-unix -x /tmp/.XIM-unix \   -x /tmp/.font-unix -x /tmp/.ICE-unix   -x /tmp/.Test-unix 240 /tmp /usr/sbin/tmpwatch "$flags" 720 /var/tmp   for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?};   do if [ -d "$d" ]; then /usr/sbin/tmpwatch "$flags" -f 720 "$d" fi done

 解決辦法:

1、修改對應應用的Djava.io.tmpdir參數,統一使用/tmp目錄。重啟應用

2、修改/etc/cron.daily/tmpwatch /usr/sbin/tmpwatch "$flags" -x /tmp/hsperfdata_* -x /tmp/.X11-unix -x /tmp/.XIM-unix -x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix 240 /tmp [root@node1 ~]# jmap -F -dump:live,format=b,file=hprof.dump 2712 Attaching to process ID 2712, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.201-b09 Dumping heap to hprof.dump ... Heap dump file created dump.hprof這個后綴是為了后續可以直接用MAT(Memory Anlysis Tool)打開。

-finalizerinfo :打印等待回收對象的信息

[root@node1 ~]# jmap -finalizerinfo 2712
Attaching to process ID 2712, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.201-b09 Number of objects pending for finalization: 0 可以看到當前F-QUEUE隊列中並沒有等待Finalizer線程執行finalizer方法的對象。

-heap :打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情況,可以用此來判斷內存目前的使用情況以及垃圾回收情況

[root@node1 ~]# jmap -heap 2712
Attaching to process ID 2712, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.201-b09 using thread-local object allocation. Parallel GC with 2 thread(s) # GC方式 Heap Configuration: // 堆內存初始化配置  MinHeapFreeRatio = 0 // 對應jvm啟動參數-XX:MinHeapFreeRatio設置JVM堆最小空閑比率(default 40)  MaxHeapFreeRatio = 100 // 對應jvm啟動參數 -XX:MaxHeapFreeRatio設置JVM堆最大空閑比率(default 70)  MaxHeapSize = 52428800 (50.0MB) // 對應jvm啟動參數-XX:MaxHeapSize=設置JVM堆的最大大小  NewSize = 17301504 (16.5MB) // 對應jvm啟動參數-XX:NewSize=設置JVM堆的‘新生代’的默認大小  MaxNewSize = 17301504 (16.5MB) // 對應jvm啟動參數-XX:MaxNewSize=設置JVM堆的‘新生代’的最大大小  OldSize = 35127296 (33.5MB) // 對應jvm啟動參數-XX:OldSize=<value>:設置JVM堆的‘老生代’的大小  NewRatio = 2 // 對應jvm啟動參數-XX:NewRatio=:‘新生代’和‘老生代’的大小比率  SurvivorRatio = 8 // 對應jvm啟動參數-XX:SurvivorRatio=設置年輕代中Eden區與Survivor區的大小比值  MetaspaceSize = 21807104 (20.796875MB) // 對應jvm啟動參數-XX:PermSize=<value>:設置JVM堆的‘永生代’的初始大小  CompressedClassSpaceSize = 1073741824 (1024.0MB) // 對應jvm啟動參數-XX:MaxPermSize=<value>:設置JVM堆的‘永生代’的最大大小  MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: // 堆內存使用情況  PS Young Generation Eden Space: // Eden區內存分布  capacity = 9961472 (9.5MB) // Eden區總容量  used = 3917840 (3.7363433837890625MB) // Eden區已使用  free = 6043632 (5.7636566162109375MB) // Eden區剩余容量 39.32993035567434% used // Eden區使用比率  From Space: // 其中一個Survivor區的內存分布  capacity = 3670016 (3.5MB) used = 1028528 (0.9808807373046875MB) free = 2641488 (2.5191192626953125MB) 28.025163922991073% used To Space: // 另一個Survivor區的內存分布  capacity = 3145728 (3.0MB) used = 0 (0.0MB) free = 3145728 (3.0MB) 0.0% used PS Old Generation // 當前的Old區內存分布  capacity = 35127296 (33.5MB) used = 27684384 (26.401885986328125MB) free = 7442912 (7.098114013671875MB) 78.81159995918843% used 20704 interned Strings occupying 2153624 bytes.

-histo :打印堆的對象統計,包括對象數、內存大小等等 (因為在dump:live前會進行full gc,如果帶上live則只統計活對象,因此不加live的堆大小要大於加live堆的大小 )

[root@node1 ~]# jmap -F -histo 2656

num #instances #bytes Class description
--------------------------------------------------------------------------
1:    526458    45456832    char[] 2: 275076 6601824 java.lang.String 3: 44613 5271264 byte[] 4: 215455 5170920 java.util.concurrent.ConcurrentSkipListMap$Node 5: 62357 4515576 int[] 6: 109775 2634600 java.lang.Double 7: 74848 2395136 java.util.HashMap$Node 8: 18442 1880400 java.util.HashMap$Node[] 9: 53471 1820904 java.lang.Object[] .... 僅僅打印了前10行 xml class name是對象類型,說明如下: B byte C char D double F float I int J long Z boolean [ 數組,如[I表示int[] [L+類名 其他對象

-F :強制模式。如果指定的pid沒有響應,請使用jmap -dump或jmap -histo選項。此模式下,不支持live子選項

另外,jmap命令生成的hprof文件可以使用jhat進行分析


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM