How to force/reproduce FullGC in JVM?

限于喜欢 提交于 2019-12-24 15:09:56

问题


Is there a way to force/reproduce FullGC in JVM for x seconds ? Basically I needed this to verify root cause of an issue in certain heart beat based app ( a client of zookeeper)

EDIT: Does unix command kill -STOP <pid> and kill -CONT <pid> simulate FullGC ( stop the world behaviour) ?


回答1:


You can simulate a very long stop-the-world event on HotSpot JVMs which is similar to FullGC from user's point of view.

HotSpot doesn't put safepoints into counted int loops, because it assumes that they will terminate just "fast enough"(In this case server compiler will generate more optimal loop code). Even a stop-the-world will have to wait until this loop will finish. In the following example we have very tight loop which do small but expensive computations without safepoint polling:

public static double slowpoke(int iterations) {
    double d = 0;
    for (int j = 1; j < iterations; j++) {
        d += Math.log(Math.E * j);
    }
    return d;
}

In order to reproduce FullGC like pause you can use something like this:

public class SafepointTest {

    public static double slowpoke(int iterations) {
        double d = 0;
        for (int j = 1; j < iterations; j++) {
            d += Math.log(Math.E * j);
        }
        return d;
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread() {
            @Override
            public void run() {
                double sideEffect = 0;
                for (int i = 0; i < 10000; i++) {
                    sideEffect = slowpoke(999999999);
                }
                System.out.println("result = " + sideEffect);
            }
        };
        thread.start();

        new Thread(){
            @Override
            public void run() {
                long timestamp = System.currentTimeMillis();
                while (true){
                    System.out.println("Delay " + (System.currentTimeMillis() - timestamp));
                    timestamp = System.currentTimeMillis();
                    //trigger stop-the-world 
                    System.gc();
                }
            }
        }.start();
        thread.join();
    }
}

As a result:

Delay 5
Delay 4
Delay 30782
Delay 21819
Delay 21966
Delay 22812
Delay 22264
Delay 21988

In order to increase delay just change argument value for slowpoke(int iterations) function.

Here is useful diagnostic commands:

  • -XX:+PrintGCApplicationStoppedTime this will actually report pause time for all safepoints into GC log. Unfortunately output from this option lacks timestamps.
  • -XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1 this two options will force JVM to report reason and timings after each safepoint.

EDIT

Regarding to Edit: from user's point of view kill -STOP and kill -CONT have the same semantics as STW i.e. application doesn't respond on any request. However, this requires access to command line and doesn't consume resources(CPU, memory).



来源:https://stackoverflow.com/questions/33917951/how-to-force-reproduce-fullgc-in-jvm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!