jmap是JDK自帶的工具軟件,主要用於打印指定Java進程(或核心文件、遠程調試服務器)的共享對象內存映射或堆內存細節。可使用jmap生成Heap Dump。在Java命令學習系列(零)——常見命令及Java Dump介紹和Java命令學習系列(二)——Jstack中分別有關於Java Dump以及線程 Dump的介紹。 這篇文章主要介紹Java的堆Dump以及jamp命令java
堆Dump是反應Java堆使用狀況的內存鏡像,其中主要包括系統信息、虛擬機屬性、完整的線程Dump、全部類和對象的狀態等。 通常,在內存不足、GC異常等狀況下,咱們就會懷疑有內存泄露。這個時候咱們就能夠製做堆Dump來查看具體狀況。分析緣由。web
Java虛擬機的內存組成以及堆內存介紹 Java GC工做原理 常見內存錯誤:算法
Usage: jmap [option] <pid> (to connect to running process) jmap [option] <executable <core> (to connect to a core file) jmap [option] [server_id@]<remote server IP or hostname> (to connect to remote debug server) where <option> is one of: <none> to print same info as Solaris pmap -heap to print java heap summary -histo[:live] to print histogram of java object heap; if the "live" suboption is specified, only count live objects -permstat to print permanent generation statistics -finalizerinfo to print information on objects awaiting finalization -dump:<dump-options> to dump java heap in hprof binary format dump-options: live dump only live objects; if not specified, all objects in the heap are dumped. format=b binary format file=<file> dump heap to <file> Example: jmap -dump:live,format=b,file=heap.bin <pid> -F force. Use with -dump:<dump-options> <pid> or -histo to force a heap dump or histogram when <pid> does not respond. The "live" suboption is not supported in this mode. -h | -help to print this help message -J<flag> to pass <flag> directly to the runtime system
指定進程號(pid)的進程 jmap [ option ] 指定核心文件 jmap [ option ] 指定遠程調試服務器jmap [ option ] [server-id@]
ubuntu
參數:瀏覽器
option 選項參數是互斥的(不可同時使用)。想要使用選項參數,直接跟在命令名稱後便可。
pid 須要打印配置信息的進程ID。該進程必須是一個Java進程。想要獲取運行的Java進程列表,你可使用jps。
executable 產生核心dump的Java可執行文件。
core 須要打印配置信息的核心文件。
remote-hostname-or-IP 遠程調試服務器的(請查看jsadebugd)主機名或IP地址。
server-id 可選的惟一id,若是相同的遠程主機上運行了多臺調試服務器,用此選項參數標識服務器。
服務器
選項: <no option>
若是使用不帶選項參數的jmap打印共享對象映射,將會打印目標虛擬機中加載的每一個共享對象的起始地址、映射大小以及共享對象文件的路徑全稱。這與Solaris的pmap工具比較類似。
-dump:[live,]format=b,file=<filename>
以hprof二進制格式轉儲Java堆到指定filename的文件中。live子選項是可選的。若是指定了live子選項,堆中只有活動的對象會被轉儲。想要瀏覽heap dump,你可使用jhat(Java堆分析工具)讀取生成的文件。
-finalizerinfo
打印等待終結的對象信息。
-heap
打印一個堆的摘要信息,包括使用的GC算法、堆配置信息和generation wise heap usage。
-histo[:live]
打印堆的柱狀圖。其中包括每一個Java類、對象數量、內存大小(單位:字節)、徹底限定的類名。打印的虛擬機內部的類名稱將會帶有一個’*’前綴。若是指定了live子選項,則只計算活動的對象。
-permstat
打印Java堆內存的永久保存區域的類加載器的智能統計信息。對於每一個類加載器而言,它的名稱、活躍度、地址、父類加載器、它所加載的類的數量和大小都會被打印。此外,包含的字符串數量和大小也會被打印。
-F
強制模式。若是指定的pid沒有響應,請使用jmap -dump或jmap -histo選項。此模式下,不支持live子選項。
-h
打印幫助信息。
-help
打印幫助信息。
-J<flag>
指定傳遞給運行jmap的JVM的參數。jvm
查看java 堆(heap)使用狀況,執行命令: hollis@hos:~/workspace/design_apaas/apaasweb/control/bin$ jmap -heap 31846
工具
Attaching to process ID 31846, please wait... Debugger attached successfully. Server compiler detected. JVM version is 24.71-b01 using thread-local object allocation. Parallel GC with 4 thread(s)//GC 方式 Heap Configuration: //堆內存初始化配置 MinHeapFreeRatio = 0 //對應jvm啓動參數-XX:MinHeapFreeRatio設置JVM堆最小空閒比率(default 40) MaxHeapFreeRatio = 100 //對應jvm啓動參數 -XX:MaxHeapFreeRatio設置JVM堆最大空閒比率(default 70) MaxHeapSize = 2082471936 (1986.0MB) //對應jvm啓動參數-XX:MaxHeapSize=設置JVM堆的最大大小 NewSize = 1310720 (1.25MB)//對應jvm啓動參數-XX:NewSize=設置JVM堆的‘新生代’的默認大小 MaxNewSize = 17592186044415 MB//對應jvm啓動參數-XX:MaxNewSize=設置JVM堆的‘新生代’的最大大小 OldSize = 5439488 (5.1875MB)//對應jvm啓動參數-XX:OldSize=<value>:設置JVM堆的‘老生代’的大小 NewRatio = 2 //對應jvm啓動參數-XX:NewRatio=:‘新生代’和‘老生代’的大小比率 SurvivorRatio = 8 //對應jvm啓動參數-XX:SurvivorRatio=設置年輕代中Eden區與Survivor區的大小比值 PermSize = 21757952 (20.75MB) //對應jvm啓動參數-XX:PermSize=<value>:設置JVM堆的‘永生代’的初始大小 MaxPermSize = 85983232 (82.0MB)//對應jvm啓動參數-XX:MaxPermSize=<value>:設置JVM堆的‘永生代’的最大大小 G1HeapRegionSize = 0 (0.0MB) Heap Usage://堆內存使用狀況 PS Young Generation Eden Space://Eden區內存分佈 capacity = 33030144 (31.5MB)//Eden區總容量 used = 1524040 (1.4534378051757812MB) //Eden區已使用 free = 31506104 (30.04656219482422MB) //Eden區剩餘容量 4.614088270399305% used //Eden區使用比率 From Space: //其中一個Survivor區的內存分佈 capacity = 5242880 (5.0MB) used = 0 (0.0MB) free = 5242880 (5.0MB) 0.0% used To Space: //另外一個Survivor區的內存分佈 capacity = 5242880 (5.0MB) used = 0 (0.0MB) free = 5242880 (5.0MB) 0.0% used PS Old Generation //當前的Old區內存分佈 capacity = 86507520 (82.5MB) used = 0 (0.0MB) free = 86507520 (82.5MB) 0.0% used PS Perm Generation//當前的 「永生代」 內存分佈 capacity = 22020096 (21.0MB) used = 2496528 (2.3808746337890625MB) free = 19523568 (18.619125366210938MB) 11.337498256138392% used 670 interned Strings occupying 43720 bytes.
查看堆內存(histogram)中的對象數量及大小。 執行命令:學習
hollis@hos:~/workspace/design_apaas/apaasweb/control/bin$ jmap -histo 3331
num #instances #bytes class name 編號 個數 字節 類名 ---------------------------------------------- 1: 7 1322080 [I 2: 5603 722368 <methodKlass> 3: 5603 641944 <constMethodKlass> 4: 34022 544352 java.lang.Integer 5: 371 437208 <constantPoolKlass> 6: 336 270624 <constantPoolCacheKlass> 7: 371 253816 <instanceKlassKlass>
jmap -histo:live 這個命令執行,JVM會先觸發gc,而後再統計信息。
this
將內存使用的詳細狀況輸出到文件, 執行命令:
hollis@hos:~/workspace/design_apaas/apaasweb/control/bin$ jmap -dump:format=b,file=heapDump 6900
而後用jhat
命令能夠參看 jhat -port 5000 heapDump
在瀏覽器中訪問:http://localhost:5000/
查看詳細信息
這個命令執行,JVM會將整個heap的信息dump寫入到一個文件,heap若是比較大的話,就會致使這個過程比較耗時,而且執行的過程當中爲了保證dump的信息是可靠的,因此會暫停應用。
1.若是程序內存不足或者頻繁GC,頗有可能存在內存泄露狀況,這時候就要藉助Java堆Dump查看對象的狀況。 2.要製做堆Dump能夠直接使用jvm自帶的jmap命令 3.能夠先使用jmap -heap
命令查看堆的使用狀況,看一下各個堆空間的佔用狀況。 4.使用jmap -histo:[live]
查看堆內存中的對象的狀況。若是有大量對象在持續被引用,並無被釋放掉,那就產生了內存泄露,就要結合代碼,把不用的對象釋放掉。 5.也可使用 jmap -dump:format=b,file=<fileName>
命令將堆信息保存到一個文件中,再借助jhat命令查看詳細內容 6.在內存出現泄露、溢出或者其它前提條件下,建議多dump幾回內存,把內存文件進行編號歸檔,便於後續內存整理分析。
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can’t attach to the process
在ubuntu中第一次使用jmap會報錯:Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process
,這是oracla文檔中提到的一個bug:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7050524,解決方式以下:
1.echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope 該方法在下次重啓前有效。
2.永久有效方法 sudo vi /etc/sysctl.d/10-ptrace.conf 編輯下面這行: kernel.yama.ptrace_scope = 1 修改成: kernel.yama.ptrace_scope = 0 重啓系統,使修改生效。