系统运行缓慢,CPU 100%,以及Full GC次数过多问题的排查思路

1. Full GC次数过多

现象
相对来说,这种情况是最容易出现的,尤其是新功能上线时。对于Full GC较多的情况,其主要有如下两个特征:
线上多个线程的CPU都超过了100%,通过jstack命令可以看到这些线程主要是垃圾回收线程
通过jstat命令监控GC情况,可以看到Full GC次数非常多,并且次数在不断增加

原因
年轻代空间不足
老年代空间不足。
永生代或者元数据空间不足。
System.gc()方法调用。
CMS GC时出现promotion failed和concurrent mode failure
YoungGC时晋升老年代的内存平均值大于老年代剩余空间
有连续的大对象需要分配

实践
1.top命令找到占用cpu过高的进程Id
2.top -Hp 10000通过进程ID查找占用cpu过高的线程Id
3.python -c ‘print hex(线程id)’ 把获取的线程Id转成16进制
4.jstack 1020|grep -C100x62fa 定位到线程池中的线程信息
VM Thread指的就是垃圾回收的线程。

总结
Full GC本身是好的,可以清除老年代的垃圾,但是如果Full GC发生的频率高了,就会影响性能,同时意味着系统内存分配机制出现问题。
因为Full GC本身执行时间较长(甚至超过1秒),而且除非采用G1 GC,否则其它的GC方式都会或多或少挂起所有线程执行(Stop-the-world),如果Full GC频繁发生,系统被挂起的次数就会增加,响应时间就会变慢。
同时,Full GC频繁发生,意味着你的内存分配机制存在问题,也许是内存泄露,有大量内存垃圾不断在老年代产生;也许是你的大对象(缓存)过多;也有可能是你的参数设置不好,minor GC清理不掉内存,导致每次minor GC都会触发Full GC;还有可能是你的老年代大小参数设置错误,老年代过小等等原因

2. CPU过高

原因
1.Full GC次数过多
2.代码中有比较耗时的计算
3.系统YGC已经不能回收太多堆内存,而FGC还没有执行,可能是因为老年代在持续增长,

3.没有fullGC,老年代持续增长

4. 不定期出现的接口耗时现象

现象
我们某个接口访问经常需要2~3s才能返回。这是比较麻烦的一种情况,因为一般来说,其消耗的CPU不多,而且占用的内存也不高

定位思路基本如下:
首先找到该接口,通过压测工具不断加大访问力度,如果说该接口中有某个位置是比较耗时的,由于我们的访问的频率非常高,那么大多数的线程最终都将阻塞于该阻塞点,这样通过多个线程具有相同的堆栈日志,我们基本上就可以定位到该接口中比较耗时的代码的位置。

5. 某个线程进入WAITING状态

现象
如果是某个功能突然出现停滞的状况,这种情况也无法复现
具体的场景
在使用CountDownLatch时,由于需要每一个并行的任务都执行完成之后才会唤醒主线程往下执行。而当时我们是通过CountDownLatch控制多个线程连接并导出用户的gmail邮箱数据,这其中有一个线程连接上了用户邮箱,但是连接被服务器挂起了,导致该线程一直在等待服务器的响应。最终导致我们的主线程和其余几个线程都处于WAITING状态
解决办法
此时可以通过多次导出jstack日志的方式对比哪些用户线程是一直都处于等待状态,这些线程就是可能存在问题的线程;

5.死锁

如果通过jstack可以查看到死锁状态,则可以检查产生死锁的两个线程的具体阻塞点,从而处理相应的问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值