GC问题分析常用工具

gc常用工具

  • https://github.com/alibaba/arthas
  • https://github.com/alibaba/TBJMap
  • https://github.com/DarLiner/vjtools/tree/master/vjmap
  • eclipse anylize
  • eclipse mat
  • jvisiualVm
  • jconsole
  • skywalking (可以生产环境实时监控,监控调用链中耗时(mysql.drive))– https://zhuanlan.zhihu.com/p/41252484 ,公司目前正在用此方式,基于java-agent
  • java profilter (可以监控调用链耗时)

jmap 虚拟机内存快照

  • jmap -heap pid (查询对应java进程的堆概况),该操作会触发GC并暂停应用
  • jmap -histo:live pid (查看堆中存活的对象) 可以搭配’>’ 导出到文件,该操作会触发GC并暂停应用,可以不适用live
  • jmap -dump:format=b,file=dumptest pid(下载dump 文件),该操作会触发GC并暂停应用

jstack java堆栈跟踪工具

  • jstack -l >jvm_listlocks.txt (查看线程中的堆栈信息)

jstat (gc 数据统计)

jstat -jcutil pid(查看堆中各个模块的百分比)
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 88.23 60.99 83.50 96.50 92.91 231 2.179 5 0.740 2.919
S0(Surivor0),S1()Surivor1),E(Eden),O(Old),M(元空间-永久代),YGC(GC 次数),YGCT(GC总时间)

visualvm

  • visualVm 是个客户端,jdk 中带的一款客户端分析jvm 工具,目前只有windows 可以使用

排查JVM 问题思路(根据现象排查)

  1. jvm 卡死的情况长时间请求未返回
    — 这种情况需要查看堆中的gc 区域是否正常
    — 如果不正常,就需要用jmap dump 下堆文件,分析对应的分区(eden、survivor、old)对应占用情况
    — 定位异常占用class,从而对应到代码创建该对象的地方,逐一排查。
  2. jvm 部分执行正常,但是线程池不执行任务或者执行缓慢,看下cpu 和 thread 数量
    — cpu 和 线程数量 正常,需要排查是否有线程锁死,通过- jstack -l >jvm_listlocks.txt 查询对应pid 的进程情况,关注下这种情况(无限期等待(Waiting):这种状态不会被分配CPU执行时间,要等待被其他线程显示唤醒,以下方法会让线程陷入无限期的等待状态。Object.wait()、Thread.join()、LockSupport.park()),由于这种等待没有超时时间,假如没有回调,则锁死了。
    — cpu 很高,线程数量较多,排除正常流量比较大的情况,有可能就是线程池使用问题,异步处理一些量比较大,而且不太重要的任务,使用策略不妥当,如使用线程池发送短信量非常大,线程池策略是CallerRunsPolicy 主线程执行。这种情况可以使用mq中间件,或者修改为丢弃策略等;

历史JVM碰到问题记录

  1. 请求无响应,生产环境
  2. job 线程池任务卡顿,无法消化线程池队列里的任务