gc日志怎么看_线上如何查看谁调用了System.gc()?

  • Post author:
  • Post category:其他


最近线上碰到了一个应用频繁full gc,但是看内存使用率却很低,感觉不是内存空间不够导致的gc,查看gc日志发现是由于显式调用了

System.gc()

导致的gc,全局搜索应用却发现应用代码中并没有调用

System.gc()

,因此怀疑是依赖的三方包中有显式调用

System.gc

的行为,那么怎么查看是谁调用了呢?

代码里找不出来,便想着看线上调用的时候能不能把调用堆栈记录下来,恰好发现了Arthas,能完美解决这个问题,使用Arthas

不需要重启应用

。见

issue

:

https://github.com/alibaba/arthas/issues/20​github.com

第一步,由于

java.lang.System

是JDK自带的类,Arthas默认关闭了对JDK类的自带类的增强,需要通过

options

命令打开

第二步,使用

stack

命令,观察谁调用了

java.lang.System#gc

本地测试代码如下:

public class PurchaseTest {
    public static void main(String[] args) throws Exception{
        System.out.println("main start");
        while(true) {
            sleep();
        }
    }
    public static void testSystemGC(){
        System.out.println("gc start");
        System.gc();
    }
    public static void sleep(){
        try {
            System.out.println("sleep start");
            TimeUnit.SECONDS.sleep(10);
        }catch (Exception e){

        }
        testSystemGC();
    }
}

监控结果如下:

9fa649180ef92f13e382659b347811b7.png

只要发生了

System.gc()

调用,便会被监控到,可以参考

issue

里把监控信息重定向到文件,这样便不用一直盯着等待

System.gc

被调用。