根据pid查询某个进程占用cpu数值_记一次应用FullGC导致服务器CPU满载进入假死状态的排查经过...

问题描述:

服务器正常启动,但一段时间后就出现CPU满载,客户端无法得到响应,服务端进入假死状态。

排查步骤:

1.看症状:CPU满载

使用top命令,发现有进程大量占用cpu资源,在top交互界面按c,显示详细command,按1可以查看每个cpu的负载情况,发现所部署的java应用大量占用CPU资源

7481759dd4d530aa921101c1eb426f81.png

2.排查导致CPU满载的线程

由第一步得到占用cpu资源的进程pid,使用top -Hp pid查看进程的线程运行信息列表。将cpu使用率高的线程PID转化为16进制,printf "%x" 13609,结合jstack工具查看到对应的堆栈信息jstack pid|grep -C5 上面得到的16进制值,得到如下图信息,可以得知为GC线程导致的cpu满载。使用jstat -gcutil pid 1000可以每秒打印应用的gc情况,得知应用的fullgc比较频繁。

bbce4b562867d52ab985daeb35144287.png

3.针对上述暴露出的内存问题,使用jprofiler对应用进行内存监控

应用启动参数加上 -agentpath:/app/jprofiler9/bin/linux-x64/libjprofilerti.so=port=8849,nowait(路径根据jprofile服务端实际情况配置),这里有个前提,服务器需要安装相同版本的jprofiler服务端。启动应用后,启动jprofile客户端连接应用进行监控。点击左端的Memory栏目,默认的heap内存的可视化界面。可以对堆内存进行异常可视化监控,如下图:

59efe0bdc19f92996923baa1c0b28721.png
4019e30ad0f3b759e5ffb8a7dd2baa3e.png

同时,点击左方的Live memory下的all Object展示所有的对象,点击界面上方的Mark current可以以当前的数据作为参考基准,可以用来看堆内存剧增时什么对象数量在增加。

bd725c5af7b1acac1932e2d7937b3234.png

由上面的堆内存监控界面,可以看到在某个时间点开始,堆内存频繁gc和递增,鼠标放到堆内存异常波动的位置上,可以得到一个时间点。而在live memory界面中,可以看到CustCoreInfo占用了228M的内存,这个明显不合理。结合两个信息a、某个时间点,堆内存开始波动 b、堆中有大量的CustCoreInfo对象,到应用日志中查看信息,可以看到以下日志

82f02d464b809213541f09982a89214b.png

发现在这个时间点,有ApproveResultNotify接口的请求,随后堆内存开始波动递增。于是进一步跟进,查看ApproveResultNotify接口代码,如下图:

9166bcf437a01f296c7d6dc23e0343a2.png
3c45c9aa535ecb6bf86aed737023cd73.png

发现代码中有一个漏洞,当loginUser没有客户号custNo时,会查全表的客户信息出来,创建上千万(生产量级)的对象出来,也符合jprofiler对象监控得到的数据(228M的CustCoreInfo对象且不被GC回收)。重新启动应用,参照上面时间点发起的请求信息,以相同的参数重新进行请求,场景重现,内存剧增。

福利时间

经过多年的技术学习和项目经验,积累了一下关于技术的视频,希望对各位有所帮助,这里免费分享给大家

998149b4f428ca8a0998c89294e6f61e.png

1.关注+转发+点赞

2.请私信发:jvm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值