频繁发生full gc,怎么排查,是什么情况导致的?

面试真题:服务提供方在qps可以接受的情况下,频繁发生full gc,怎么排查,是什么情况导致的

问题:gc的原因 频繁full_CPU飙高,频繁GC,怎么排查?

总结:
这种情况可能的原因主要有两种:

1.代码中某个位置读取数据量较大,导致系统内存耗尽,从而导致Full GC次数过多,系统缓慢;
2.代码中有比较耗CPU的操作,导致CPU过高,系统运行缓慢;

1. Full GC次数过多
对于Full GC较多的情况,其主要有如下两个特征:

1.线上多个线程的CPU都超过了100%,通过jstack命令可以看到这些线程主要是垃圾回收线程
2.通过jstat命令监控GC情况,可以看到Full GC次数非常多,并且次数在不断增加

对于Full GC次数过多,主要有以下两种原因:

1.代码中一次获取了大量的对象,导致内存溢出,此时可以通过eclipse的mat工具查看内存中有哪些对象比较多;
2.内存占用不高,但是Full GC次数还是比较多,此时可能是显示的 System.gc()调用导致GC次数过多,这可以通过添加 -XX:+DisableExplicitGC来禁用JVM对显示GC的响应。

排查?

1.首先我们可以使用top命令查看系统CPU的占用情况

2.接下来我们可以通过jstack命令查看线程id为X的线程为什么耗费CPU最高

3.如果发现full gc数量不断增长,进一步证实了是由于内存溢出导致的系统缓慢。那么这里确认了内存溢出,但是如何查看你是哪些对象导致的内存溢出呢,这个可以dump出内存日志,然后通过eclipse的mat工具进行查看

4.经过mat工具分析之后,我们基本上就能确定内存中主要是哪个对象比较消耗内存,然后找到该对象的创建位置,进行处理即可

2. CPU过高

CPU过高可能是系统频繁的进行Full GC,导致系统缓慢。而我们平常也肯能遇到比较耗时的计算,导致CPU过高的情况,

查看方式:

1.首先我们通过top命令查看当前CPU消耗过高的进程是哪个,从而得到进程id;
2.然后通过top -Hp来查看该进程中有哪些线程CPU过高,一般超过80%就是比较高的,80%左右是合理情况。这样我们就能得到CPU消耗比较高的线程id。
3.接着通过该线程id的十六进制表示在jstack日志中查看当前线程具体的堆栈信息。

4.在这里我们就可以区分导致CPU过高的原因具体是Full GC次数过多还是代码中有比较耗时的计算了。
5.如果是Full GC次数过多,那么通过jstack得到的线程信息会是类似于VM Thread之类的线程,而如果是代码中有比较耗时的计算,那么我们得到的就是一个线程的具体堆栈信息。

你可能感兴趣的:(面试真题,jvm,java,面试)