解決jmap命令打印JVM堆信息異常的問題
jmap命令可以打印java進(jìn)程的JVM堆信息,今天在某臺(tái)機(jī)器上運(yùn)行該命令查看 19560進(jìn)程的堆信息
jmap -heap 19560
出現(xiàn)以下異常
Attaching to process ID 19560, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.79-b02
using thread-local object allocation.
Parallel GC with 33 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 32038191104 (30554.0MB)
NewSize = 1310720 (1.25MB)
MaxNewSize = 17592186044415 MB
OldSize = 5439488 (5.1875MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 21757952 (20.75MB)
MaxPermSize = 174063616 (166.0MB)
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sun.tools.jmap.JMap.runTool(JMap.java:197)
at sun.tools.jmap.JMap.main(JMap.java:128)
Caused by: java.lang.RuntimeException: unknown CollectedHeap type : class sun.jvm.hotspot.gc_interface.CollectedHeap
at sun.jvm.hotspot.tools.HeapSummary.run(HeapSummary.java:146)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
at sun.jvm.hotspot.tools.HeapSummary.main(HeapSummary.java:40)
... 6 more
是因?yàn)闄C(jī)器上缺少 openjdk-debuginfo 包 或者 機(jī)器上的 openjdk-debuginfo 包與jdk版本不一致導(dǎo)致
是用 java -version 查看機(jī)器上的java版本
java version "1.7.0_79"
OpenJDK Runtime Environment (rhel-2.5.5.4.el6-x86_64 u79-b14)
OpenJDK 64-Bit Server VM (build 24.79-b02, mixed mode)
到 http://debuginfo.centos.org/6/x86_64/ 網(wǎng)站上去查找和jdk版本對(duì)應(yīng)的debuginfo包,我的jdk版本是 1.7.0_79,所以頁面展示完所有的包后,搜索 openjdk-debuginfo-1.7.0.79,總共出現(xiàn)了三個(gè)包
java-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.1.el6_6.x86_64.rpm
java-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.3.el6_6.x86_64.rpm
java-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.4.el6.x86_64.rpm
均滿足我的jdk版本,下載第一個(gè)進(jìn)行嘗試,下載完成后使用 rpm命令安裝
rpm -ivh java-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.1.el6_6.x86_64.rpm
安裝完成后使用查看是否在已安裝列表中,執(zhí)行命令顯示的確安裝成功
[root@identity_test tmp]# rpm -qa |grep debuginfo
java-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.1.el6_6.x86_64
再次執(zhí)行我最初想執(zhí)行的命令
jmap -heap 19560
已經(jīng)能正常顯示JVM堆區(qū)信息
Attaching to process ID 19560, please wait... Debugger attached successfully. Server compiler detected. JVM version is 24.79-b02 using thread-local object allocation. Parallel GC with 33 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 32038191104 (30554.0MB) NewSize = 1310720 (1.25MB) MaxNewSize = 17592186044415 MB OldSize = 5439488 (5.1875MB) NewRatio = 2 SurvivorRatio = 8 PermSize = 21757952 (20.75MB) MaxPermSize = 174063616 (166.0MB) G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 537919488 (513.0MB) used = 532557632 (507.88653564453125MB) free = 5361856 (5.11346435546875MB) 99.00322332252071% used From Space: capacity = 89128960 (85.0MB) used = 0 (0.0MB) free = 89128960 (85.0MB) 0.0% used To Space: capacity = 89128960 (85.0MB) used = 0 (0.0MB) free = 89128960 (85.0MB) 0.0% used PS Old Generation capacity = 1431306240 (1365.0MB) used = 844440 (0.8053207397460938MB) free = 1430461800 (1364.194679260254MB) 0.058997856391655217% used PS Perm Generation capacity = 22020096 (21.0MB) used = 8512616 (8.118263244628906MB) free = 13507480 (12.881736755371094MB) 38.65839640299479% used 3145 interned Strings occupying 252104 bytes.
補(bǔ)充知識(shí):JVM參數(shù),jmap打印堆快照,jstack實(shí)戰(zhàn)死鎖
1 jinfo指令:如何運(yùn)行時(shí)查看參數(shù)值
jinfo -flag MaxHeapSize 23789(查看最大堆:23789即線程id)
jinfo -flag ThreadStackSize 23789(查詢線程棧大小:默認(rèn)值1024)
2 查看jvm運(yùn)行時(shí)參數(shù)
(1)-XX:+PrintFlagsInitial 查看初始值

=表示默認(rèn)值
:=被用戶或者JVM修改后的值
(2)-XX:+PrintFlagsFinal表示打印出運(yùn)行時(shí)參數(shù)生效的值
-XX:+UnlockExperimentalVMOptions解鎖實(shí)驗(yàn)參數(shù)(并非所有的參數(shù)都可以直接修改)
(3)jps
jps是用于查看有權(quán)訪問的hotspot虛擬機(jī)的進(jìn)程. 當(dāng)未指定hostid時(shí),默認(rèn)查看本機(jī)jvm進(jìn)程,否者查看指定的hostid機(jī)器上的jvm進(jìn)程,此時(shí)hostid所指機(jī)器必須開啟jstatd服務(wù)。 jps可以列出jvm進(jìn)程lvmid,主類類名,main函數(shù)參數(shù), jvm參數(shù),jar名稱等信息。
(4)jinfo -flag 23789(查看tomcat進(jìn)程23789運(yùn)行時(shí)jvm參數(shù))
jinfo -flag UseParallelGC 23789
jinfo -flag UseG1GC 23789
jinfo -flag UseConcMarkSweepGC 23789
(5)jstat 查看JVM統(tǒng)計(jì)信息,例如類加載信息、垃圾收集、JIT編譯
jstat -class 23789 加載了多少個(gè)類,占用多少Kb,卸載多少個(gè),平臺(tái)卸載加載所花費(fèi)時(shí)間
jstat -gc 23789
jstat -gc 23789 1000 10 (每個(gè)1秒打印gc信息,共打印10次)


Metaspace里面有ccs, CodeCache等ccs表示啟用指向自己類文件的短指針的時(shí)候就會(huì)存在ccs。CodeCache:存放jit編譯代碼信息。把java代碼轉(zhuǎn)化為native代碼。
(6)jmap+MAT實(shí)戰(zhàn)內(nèi)存溢出
①導(dǎo)出內(nèi)存映射文件:
自動(dòng)導(dǎo)出:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./
jmap命令手動(dòng)導(dǎo)出:
jmap -dump:format=b,file=heap.hprof 23789
我們實(shí)驗(yàn)的時(shí)候在eclipse debug添加參數(shù):
-Xms23m -Xmx23m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./
②導(dǎo)入mat中分析:
File -> openFile ->導(dǎo)入自己的文件heap.hprof
查看可能存在內(nèi)存溢出:

查看類占用內(nèi)存大小

正則匹配查看我們的類占用內(nèi)存大小(shallow heap不包括其內(nèi)部引用對(duì)象大小)
(7)jstack 查看線程
jstack 23789 > 23789.txt
注意: top命令查看pid是十進(jìn)制的,printf “%x” 23789 就將23789轉(zhuǎn)化為16進(jìn)制5ced。然后在23789.txt中搜索ox5ced,就能找到pid對(duì)應(yīng)的類信息
死循環(huán)案例分析:
private Object lock1 = new Object();
private Object lock2 = new Object();
public String deadlock() {
new Thread(() -> {
synchronized(lock1) {
synchronized(lock1) {System.out.println(“Thread1 get lock1”)}
try{Thread.sleep(5000);}cache(Exception e){}
synchronized(lock2) {System.out.println(“Thread1 get lock2”)}
}
}).start();
new Thread(() -> {
synchronized(lock2) {
synchronized(lock1) {System.out.println(“Thread2 get lock2”)}
try{Thread.sleep(5000);}cache(Exception e){}
synchronized(lock1) {System.out.println(“Thread2 get lock1”)}
}
}).start();
}
jstack 線程id > 線程id.txt

在文件末尾,我們就可以看到明顯的死鎖信息。
以上這篇解決jmap命令打印JVM堆信息異常的問題就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringCloud學(xué)習(xí)筆記之Feign遠(yuǎn)程調(diào)用
Feign是一個(gè)聲明式的http客戶端。其作用就是幫助我們優(yōu)雅的實(shí)現(xiàn)http請(qǐng)求的發(fā)送。本文將具體為大家介紹一下Feign的遠(yuǎn)程調(diào)用,感興趣的可以了解一下2021-12-12
SpringBoot整合RocketMQ實(shí)現(xiàn)發(fā)送同步消息
RocketMQ 是一款開源的分布式消息中間件,由阿里巴巴開源,它具有高可用性、高性能、低延遲等特點(diǎn),廣泛應(yīng)用于阿里巴巴集團(tuán)內(nèi)部以及眾多外部企業(yè)的業(yè)務(wù)系統(tǒng)中,本文給大家介紹了SpringBoot整合RocketMQ實(shí)現(xiàn)發(fā)送同步消息,需要的朋友可以參考下2024-04-04
Java Mybatis框架增刪查改與核心配置詳解流程與用法
MyBatis 是一款優(yōu)秀的持久層框架,它支持自定義 SQL、存儲(chǔ)過程以及高級(jí)映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過簡(jiǎn)單的 XML 或注解來配置和映射原始類型、接口和 Java POJO為數(shù)據(jù)庫中的記錄2021-10-10
Java8?LocalDateTime時(shí)間日期類使用實(shí)例詳解
本文從 LocalDateTime 類的創(chuàng)建、轉(zhuǎn)換、格式化與解析、計(jì)算與比較以及其他操作幾個(gè)方面詳細(xì)介紹了 LocalDateTime 類在 Java 8 中的使用,感興趣的朋友跟隨小編一起看看吧2024-03-03
Struts2中圖片以base64方式上傳至數(shù)據(jù)庫
這篇文章主要介紹了Struts2中圖片以base64方式上傳至數(shù)據(jù)庫的實(shí)現(xiàn)代碼,代碼分為前臺(tái)和后臺(tái)兩段,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09

