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 and kill -CONT simulate FullGC ( stop the world behaviour) ?

解决方案

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).

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐