2019独角兽企业重金招聘Python工程师标准>>>

通过使用 JVM 自带的工具 jstack,jmap,jstat 排查java程序占用内存或cpu负载过高的问题。

理论部分

jstack - Prints Java thread stack traces for a Java process, core file, or remote debug server.

打印线程堆栈信息

命令行使用:

jstack <pid> 获取到 jvm 进程的所有堆栈信息

jmap - Prints shared object memory maps or heap memory details for a process, core file, or remote debug server.

打印内存中的对象以及堆内存信息

命令行使用:

jmap -heap <pid> 获取 jvm 进程的堆内存配置以及使用情况

jmap -histo <pid> 获取 jvm 进程的在内存中创建的对象数量

jmap -dump:format=b,file=heap.bin <pid> 导出内存文件,这个文件可以通过导入eclipse的MemoryAnalyzer来分析

jstat - Monitors Java Virtual Machine (JVM) statistics.

监控 jvm 获取一些统计信息,classloader,compiler,gc相关

命令行使用:

jstat [option] <pid>

参数列表(上面那个 option):

-class:统计class loader行为信息 
-compile:统计编译行为信息 
-gc:统计jdk gc时heap信息 
-gccapacity:统计不同的generations(不知道怎么翻译好,包括新生区,老年区,permanent区)相应的heap容量情况 
-gccause:统计gc的情况,(同-gcutil)和引起gc的事件 
-gcnew:统计gc时,新生代的情况 
-gcnewcapacity:统计gc时,新生代heap容量 
-gcold:统计gc时,老年区的情况 
-gcoldcapacity:统计gc时,老年区heap容量 
-gcpermcapacity:统计gc时,permanent区heap容量 
-gcutil:统计gc时,heap情况

输出内容:

S0  — Heap上的 Survivor space 0 区已使用空间的百分比 
S0C:S0当前容量的大小 
S0U:S0已经使用的大小 
S1  — Heap上的 Survivor space 1 区已使用空间的百分比 
S1C:S1当前容量的大小 
S1U:S1已经使用的大小 
E   — Heap上的 Eden space 区已使用空间的百分比 
EC:Eden space当前容量的大小 
EU:Eden space已经使用的大小 
O   — Heap上的 Old space 区已使用空间的百分比 
OC:Old space当前容量的大小 
OU:Old space已经使用的大小 
P   — Perm space 区已使用空间的百分比 
OC:Perm space当前容量的大小 
OU:Perm space已经使用的大小 
YGC — 从应用程序启动到采样时发生 Young GC 的次数 
YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒) 
FGC — 从应用程序启动到采样时发生 Full GC 的次数 
FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒) 
GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

实战部分

线上环境存在一台服务器(centos 7)cpu使用率一直处于报警状态。

在使用上面3个命令的时候如果出现

Error attaching to process: sun.jvm.hotspot.runtime.VMVersionMismatchException: Supported vertion are 25.65-b01. Target VM is 25.121-b13

说明工具的版本和启动程序的jvm版本不一致,去oracle官网下载对应版本的jdk工具 传送门,我使用的是jdk1.8 红色部分是需要下载的小的版本 号 即jdk1.8_121

使用 top 命令查看cpu使用率

发现一个 pid 为 30996 的cpu使用率特别高,再次使用 top -Hp 30996 命令查看这个进程的线程使用情况

31036 这个就是有问题的线程,使用 printf "%x\n" 31036 转换成16进制(下面有用)

接着就可以使用 jstack 命令查看这个线程的堆栈情况 jstack 30996 | grep -A 10 793c (30996是刚才查到有问题的进程 793c为16进制线程号 grep -A 10 为查到793c那一行之后向下再打印10行)

这个 nid=0x793c 的 Thread-14 线程就是问题线程,多次执行命令查看之后发现代码一直运行在 MasterEngine.java 48行。然后就可以去查看代码了。

看上去在迭代一个map,循环删除。

再看下其他地方

执行 jmap -histo 30996 | head -n 20 看下内存中创建类top20的情况

连续调用4次发现 java.util.concurrent.ConcurrentHashMap$EntryIterator 实例数量在不断增大然后突然又变小了。猜测是实例被 gc 快速回收掉了。

那么再用 jstat -gcutil 30996 2000 20 看下 gc 执行情况 (2000 200 是指每隔2秒执行一次 一共执行20次)

看YGC这一列(从右边往左第五列),young gc 执行了 2千8百万多次。

再用 gccapacity 参数看一下堆的情况

只有Eden space (第6列)的大小在发生变化

再看下 jvm 堆的配置情况 jmap -heap 30996

配置了最大堆大小(MaxHeapSize)是 4g,Eden Space 45%, From Space 18%,To Space 0%,Old Generation 73%

再看下服务器负载情况,命令就是一个 w

最后三个数字表示服务器最近 1分钟 5分钟 15分钟 的平均负载,超过cpu核数*1(4核就是4 8核就是8)表示服务器负载非常大。现在这个数字看上去服务器负载比较小还是能够应对。

总结

结合以上各种迹象,基本可以断定问题就出在对map进行迭代删除的代码,频繁创建 ConcurrentHashMap$EntryIterator 实例,频繁触发 young gc,是导致 cpu 占用过高的原因。堆大小的占用情况还可以,负载还能接受,内存硬盘都正常(忘记截图了),full gc 次数没有特别多。更加具体的原因还需要了解代码作者的用意。

所以,只要会使用 jmap jstack jstat 这3个工具,还有一些linux的基本命令(检查磁盘 网络 等等),就可以从容应对因为 代码写得太烂 造成程序异常的情况。

转载于:https://my.oschina.net/u/232911/blog/2245724

JVM 排查问题实战相关推荐

  1. 七、JVM调优实战——基本命令使用

    一.JVM类加载机制--自定义类加载器 二.JVM--对象内存分配机制 三.JVM内存模型 四.JVM垃圾收集算法和垃圾收集器 五.CMS垃圾回收器--三色标记算法 六.G1垃圾收集器 七.JVM调优 ...

  2. JVM调优实战:to-space exhausted Evacuation Failure

    一次线上dubbo问题的定位,进行JVM调优实战. 问题 线上dubbo接口provider抛出异常: org.apache.dubbo.rpc.RpcException: Failfast invo ...

  3. 纯手写2022年最新JVM调优实战手册,看完让你精通JVM调优

    很多程序员不重视 JVM 内存调优,写出来的代码经常出现 OOM 等内存问题.而且,面试求职者中,很多求职者一旦遇到JVM 或者 JVM 调优方面的问题,往往不知如何回答,才能充分展现自己的能力. j ...

  4. java old区_一次Jvm old过高的排查过程实战记录

    前言 最近遇到一个Jvm old过高的案例,现象是一个站点的jvm old区过高,分析原因是,原来的设计方案有问题,给前端返回的数据里面包含了大量的html代码,从存储中拿数据的过程.拼接数据的过程过 ...

  5. JVM调优实战:G1中的to-space exhausted问题

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 作者:阿杜 来源:公众号「javaadu」 >> 「开学季」当当大促!4-5折优 ...

  6. JVM 调优实战--常见的垃圾回收算法及垃圾收集器组合

    什么是垃圾 C语言申请内存:malloc free C++: new delete c/C++ 手动回收内存 Java: new ? 自动内存回收,编程上简单,系统不容易出错,手动释放内存,容易出两种 ...

  7. 带你感受一次JVM调优实战

    本文分成两部分,先了解理论,然后再进行实战. 理论篇 1.1 调优目标 JVM调优的两大目标是: 提高应用程序的性能和吞吐量: 通过优化JVM的垃圾回收机制.调整线程池大小和优化代码,可以提高应用程序 ...

  8. JVM 调优实战--JVM的运行参数及jinfo查看运行参数信息

    为什么要进行JVM优化? 本篇博文基于jdk1.8来讲解. JVM的参数 标准参数比较稳定,基本上各个不同的jdk版本都会支持. -X参数是非标参数,各个版本不同,可能用着用着就没了. -XX参数也属 ...

  9. JVM从入门到精通(九):JVM调优实战 - arthas 的使用

    Arthas 文档 https://github.com/alibaba/arthas/blob/master/README_CN.md 运行起来我们的java程序 启动 arthas 的 jar 文 ...

最新文章

  1. qt中初始化界面的几种方法
  2. 使用read_html爬取网页表哥,Python笔记:用read_html()爬取table形式表格的网络数据...
  3. C/C++中char *与wchar_t*的几种转换方法
  4. 基于变长PSO的高维特征选择算法(VLPSO)概述
  5. 【生信进阶练习1000days】day8-OrganismDb.dplyr包
  6. 转:面对失败,我们只是固执地想证明之前的决策是对的
  7. 拒绝“重复造轮子”,百度EasyDL让你玩转AI定制开发
  8. 企业管理不可忽视“工作日志”
  9. ESP8266-01 MQTT固件烧录并连接阿里云服务器
  10. 【金猿技术展】视频矫正技术——基于参数估计的自由几何变换算法
  11. 打印101~150之间的质数
  12. 【Windows Esp32】基于 libjpeg-9e 编解码库的视频播放器
  13. 《液晶显示器和液晶电视维修核心教程》——2.7 光电耦合器
  14. Swift 类型的检査与转换(is,as,AnyObject,Any)
  15. redhat linux下安装jq和jq的简单应用
  16. 【MySQL高可用】MySQL高可用之MGR部署
  17. 【Simulink+Prescan笔记】控件介绍
  18. 滴答顺风车怎么抢90%以上的订单_顺风车这样做才是对的,其他都是扯淡!
  19. 发明专利申请过程及案例下载
  20. 【JZOJ3301】家族

热门文章

  1. 2017安防市场新趋势:硬件免费 服务收费
  2. 惠普企业(HPE)是否免不了最终被关停的命?
  3. Unity教程之-Unity3d中针对Android Apk的签名验证(C#实现)
  4. BIOS基础知识(上)
  5. zabbix 客户端自定义端口监控
  6. end_request: I/O error
  7. 使用SQL语句添加和删除约束
  8. sharepoint小 tip
  9. 离线安装老版本android sdk,亲测,linux、windows、mac通用
  10. try catch 对于循环体,应放在外面还是里面?