使用jmap命令观察JAVA堆情况
jmap
(Memory Map for Java)命令用于生成堆转储快照。 如果不使用 jmap
命令,要想获取 Java 堆转储,使用 “-XX:+HeapDumpOnOutOfMemoryError”
参数,可以让虚拟机在 OOM 异常出现之后自动生成 dump 文件;Linux 命令下可以通过 kill -3
发送进程退出信号也能拿到 dump 文件。
jmap
的作用并不仅仅是为了获取 dump 文件,它还可以查询 finalizer 执行队列、Java 堆和永久代的详细信息,如空间使用率、当前使用的是哪种收集器等。
以下例子以onos程序(pid为29785)为例:
使用 -finalizerinfo
查看正等候回收的对象的信息,以下输出表示没有对象等待被finalization。
jmap -finalizerinfo pid
使用histo
用来输出java heap对象的直方图。可以加一个live
选项,用来输出live的对象。因为打印的结果太多,一下只截取部分内容
jmap -histo pid
jmap -histo:live pid
其中num是对象的编号,instances是对象的个数,bytes是对象的大小,class name是对象的class名字。
使用clstats
输出类加载有关的统计信息。这里因为onos打印出来的话太多了根本截不到表头,因此以上一个死锁实验的JAVA进程为例(pid为2608)。
jam -clstats pid
其中各列的含义如下:
- Index - class的编号
- Super - 父类的编号
- InstBytes - 每个instance的bytes大小
- KlassBytes - 该class的bytes大小
- annotations - 注解大小
- CpAll - 每个class中constants, tags, cache, 和 operands的大小
- MethodCount - class中方法的个数
- Bytecodes - byte codes的大小
- MethodAll - method, CONSTMETHOD, stack map, 和 method data的大小
- ROAll - 可以放到read-only memory中的class元数据的大小
- RWAll - 可以放到read/write memory中的class元数据大小
- Total - ROAll + RWAll
- ClassName - class name
使用dump
生成堆转储快照,dump
用于dump整个java heap,dump
可以接三个参数(多参数用英文逗号隔开):
- live - dump live对象
- format=b - 以hprof的二进制模式dump
- file=filename - dump对象到文件中
jmap -dump:live,file=xxx.hprof pid
因为导出的文件特别大,因此需要用到相关的工具如接下来将要实践的MAT(eclipse Memory Analyzer Tool)、Visual VM等。
jmap命令
命令格式
jmap [ option ] pid
jmap [ option ] executable core
jmap [ option ] [server-id@] remote-hostname-or-IP
参数说明
1)options:
executable:Java executable from which the core dump was produced.
(可能是产生core dump的java可执行程序)
core:将被打印信息的core dump文件
remote-hostname-or-IP:远程debug服务的主机名或ip
server-id:唯一id,假如一台主机上多个远程debug服务
2)基本参数:
-dump:[live,]format=b,file= 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件. -finalizerinfo 打印正等候回收的对象的信息.
-heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
-histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量.
-permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来.
-F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.
-h | -help 打印辅助信息
-J 传递参数给jmap启动的jvm.
3)pid
pid 需要被打印配置信息的java进程id,可以用jps查询.
jmap使用错误以及解决方法
1、java进程禁止在运行中时被用户访问内存和状态
使用jmap可能会出现以下错误:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9p1ikIa2-1610593187176)(/home/lxj/.config/Typora/typora-user-images/1610508002017.png)]
这是因为ptrace-scope
为了防止用户访问当前正在运行的进程的内存和状态 , 默认情况下不允许再访问了.
临时开启(/proc/sys/kernel/yama/ptrace_scope
中的内容默认为1,0:允许, 1:不允许):
echo 0 > /proc/sys/kernel/yama/ptrace_scope
永久开启:
/etc/sysctl.d/10-ptrace.conf
添加或修改为以下这一句:
kernel.yama.ptrace_scope = 0