JVM调优-工具篇-JMAP/jstack/jcmd

jmap常用来查看jvm内存的使用情况。

一,jmap

1,jmap -dump

1.1,手动dump

jmap -dump命令将jvm内存使用情况以二进制形式保存到文件当中,通过jprofile或者jdk自带工具bin目录下jVisualVM查看。

使用方式如下:

// 所有对象
 jmap -dump:format=b,file=<filename.hprof> <pid>
// 存活对象
jmap -dump:live,format=b,file=<filename.hprof> <pid>
选项作用
dump生成dump文件(Java堆转储快照),-dump:live只保存堆中的存活对象
-heap输出整个堆空间的详细信息,包括GC的使用、堆配置信息,以及内存的使用信息等
-histo输出堆空间中对象的统计信息:类、实例数量和合计容量,-histo:live只统计存活对象
-J 传递参数给jmap启动的jvm
-finalizerinfo显示在F-Queue中等待Finalizer线程执行finalize方法的对象,仅linux/solaris平台有效
-permstat以ClassLoader为统计口径输出永久代的内存状态信息,仅linux/solaris平台有效
-F当虚拟机进程对-dump选项没有任何响应时,强制生成dump文件
1.2,自动dump

要获取内存的dump文件,除了上述手动执行方式,还可以通过在启动程序时加命令行参数,在jvm oom之前把dump文件保存至指定文件。

需要配合另外一个指令文件的参数:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\study\log_hprof\gc.hprof
1.3,jvisualVM打开dump文件

可以看到堆内对象的大小排序,据此可以找出堆中的大对象,判断是否出现了内存泄漏,或者其他什么问题。
在这里插入图片描述

1.4,区别

自动dump和手动dump的区别在于手动dump可以服务器性能出现问题的时候使用,而自动dump一定出现oom才会dump,使用场景比较单一。

2,jmap -heap

查看jvm内存空间的统计信息,如下:

jmap -heap 3307
Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 22413312 (21.375MB)
   used     = 19915896 (18.99327850341797MB)
   free     = 2497416 (2.3817214965820312MB)
   88.8574432908443% used
Eden Space:
   capacity = 19922944 (19.0MB)
   used     = 18848104 (17.974952697753906MB)
   free     = 1074840 (1.0250473022460938MB)
   94.60501419870477% used
From Space:
   capacity = 2490368 (2.375MB)
   used     = 1067792 (1.0183258056640625MB)
   free     = 1422576 (1.3566741943359375MB)
   42.87687602796053% used
To Space:
   capacity = 2490368 (2.375MB)
   used     = 0 (0.0MB)
   free     = 2490368 (2.375MB)
   0.0% used
tenured generation:
   capacity = 49659904 (47.359375MB)
   used     = 31271600 (29.822921752929688MB)
   free     = 18388304 (17.536453247070312MB)
   62.97152729091059% used

3,jmap -histo

jmap -histo可以查看堆内存中的对象数量、内存占用大小,这部分内容在dump文件中也可以看到。

jmap -histo 3037 | head -n 10

结果:

 num     #instances         #bytes  class name
   1:             4       13762624  [Lorg.apache.hadoop.util.LightWeightGSet$LinkedElement;
   2:         17562        9074832  [B
   3:         48224        4512896  [C
   4:          6713        2721424  [I
   5:         43512        1044288  java.lang.String
   6:          7975         900664  java.lang.Class
   7:          9301         715544  [Ljava.lang.Object;

4,总结

  • 由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。

  • 举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么:live选项将无法探知到这些对象。

  • 另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去。与前面讲的jstat则不同,垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jstat只需直接读取即可。

二,jstack

jstack(JVM Stack Trace):用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)。

线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。

生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用jstack显示各个线程调用的堆栈情况。

在thread dump中,要留意下面几种状态

  • 死锁,Deadlock(重点关注)
  • 等待资源,Waiting on condition(重点关注)
  • 等待获取监视器,Waiting on monitor entry(重点关注)
  • 阻塞,Blocked(重点关注)
  • 执行中,Runnable
  • 暂停,Suspended
  • 对象等待中,Object.wait() 或 TIMED_WAITING
  • 停止,Parked
option参数作用
-F当正常输出的请求不被响应时,强制输出线程堆栈
-l除堆栈外,显示关于锁的附加信息
-m如果调用本地方法的话,可以显示C/C++的堆栈

使用方法:

jstack  pid
jstack 77932

在这里插入图片描述

三,jcmd

一个综合性的命令,可以实现jmap、jstack、jstat、jps等命令的功能。

使用方法:

  • jcmd -l 相当于 jps
  • jcmd pid help查看某个线程可以使用的命令
  • jcmd pic param param 来自上一步jcmd pid help的结果
1,jcmd -l

在这里插入图片描述

2,jcmd 3037 help

在这里插入图片描述

3, jcmd 3307 Thread.print

Thread.print来自于上一步的查找结果,相当于jstack的效果

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值