欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

解决jmap命令打印JVM堆信息异常的问题

程序员文章站 2022-03-03 09:24:29
jmap命令可以打印java进程的jvm堆信息,今天在某台机器上运行该命令查看 19560进程的堆信息jmap -heap 19560出现以下异常attaching to process id 195...

jmap命令可以打印java进程的jvm堆信息,今天在某台机器上运行该命令查看 19560进程的堆信息

jmap -heap 19560

出现以下异常

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

是因为机器上缺少 openjdk-debuginfo 包 或者 机器上的 openjdk-debuginfo 包与jdk版本不一致导致

是用 java -version 查看机器上的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/ 网站上去查找和jdk版本对应的debuginfo包,我的jdk版本是 1.7.0_79,所以页面展示完所有的包后,搜索 openjdk-debuginfo-1.7.0.79,总共出现了三个包

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版本,下载第一个进行尝试,下载完成后使用 rpm命令安装

rpm -ivh java-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.1.el6_6.x86_64.rpm

安装完成后使用查看是否在已安装列表中,执行命令显示的确安装成功

[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

再次执行我最初想执行的命令

jmap -heap 19560

已经能正常显示jvm堆区信息

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.

补充知识:jvm参数,jmap打印堆快照,jstack实战死锁

1 jinfo指令:如何运行时查看参数值

jinfo -flag maxheapsize 23789(查看最大堆:23789即线程id)

jinfo -flag threadstacksize 23789(查询线程栈大小:默认值1024)

2 查看jvm运行时参数

(1)-xx:+printflagsinitial 查看初始值

解决jmap命令打印JVM堆信息异常的问题

=表示默认值

:=被用户或者jvm修改后的值

(2)-xx:+printflagsfinal表示打印出运行时参数生效的值

-xx:+unlockexperimentalvmoptions解锁实验参数(并非所有的参数都可以直接修改)

(3)jps

jps是用于查看有权访问的hotspot虚拟机的进程. 当未指定hostid时,默认查看本机jvm进程,否者查看指定的hostid机器上的jvm进程,此时hostid所指机器必须开启jstatd服务。 jps可以列出jvm进程lvmid,主类类名,main函数参数, jvm参数,jar名称等信息。

(4)jinfo -flag 23789(查看tomcat进程23789运行时jvm参数)

jinfo -flag useparallelgc 23789

jinfo -flag useg1gc 23789

jinfo -flag useconcmarksweepgc 23789

(5)jstat 查看jvm统计信息,例如类加载信息、垃圾收集、jit编译

jstat -class 23789 加载了多少个类,占用多少kb,卸载多少个,平台卸载加载所花费时间

jstat -gc 23789

jstat -gc 23789 1000 10 (每个1秒打印gc信息,共打印10次)

解决jmap命令打印JVM堆信息异常的问题

解决jmap命令打印JVM堆信息异常的问题

metaspace里面有ccs, codecache等ccs表示启用指向自己类文件的短指针的时候就会存在ccs。codecache:存放jit编译代码信息。把java代码转化为native代码。

(6)jmap+mat实战内存溢出

①导出内存映射文件:

自动导出:

-xx:+heapdumponoutofmemoryerror -xx:heapdumppath=./

jmap命令手动导出:

jmap -dump:format=b,file=heap.hprof 23789

我们实验的时候在eclipse debug添加参数:

-xms23m -xmx23m -xx:+heapdumponoutofmemoryerror -xx:heapdumppath=./

②导入mat中分析:

file -> openfile ->导入自己的文件heap.hprof

查看可能存在内存溢出:

解决jmap命令打印JVM堆信息异常的问题

查看类占用内存大小

解决jmap命令打印JVM堆信息异常的问题

正则匹配查看我们的类占用内存大小(shallow heap不包括其内部引用对象大小)

(7)jstack 查看线程

jstack 23789 > 23789.txt

注意: top命令查看pid是十进制的,printf “%x” 23789 就将23789转化为16进制5ced。然后在23789.txt中搜索ox5ced,就能找到pid对应的类信息

死循环案例分析:

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堆信息异常的问题

在文件末尾,我们就可以看到明显的死锁信息。

以上这篇解决jmap命令打印jvm堆信息异常的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。