如何在JVM中强制/重现FullGC? [英] How to force/reproduce FullGC in JVM?

查看:5529
本文介绍了如何在JVM中强制/重现FullGC?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在JVM中强制/重现FullGC x秒?基本上我需要这个来验证在某些基于心跳的应用(动物园管理员的客户)中问题的根本原因。



编辑:unix命令 kill -STOP< pid> kill -CONT< pid> 模拟FullGC(停止世界行为)?

解决方案

您可以在HotSpot JVM上模拟一个非常长的停止世界事件,与用户的观点类似于FullGC 。

HotSpot不会将 safepoints 进入计数的int循环,因为它假设它们只会足够快地终止(在这种情况下,服务器编译器会生成更多的最佳循环代码)。即使是停下来的世界也必须等到这个循环结束。在下面的例子中,我们有非常紧凑的循环,它们在没有安全点轮询的情况下进行小而昂贵的计算:

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

$ / code>

为了重现FullGC像暂停,你可以使用像这样的东西:

  public class SafepointTest {

public static double slowpoke(int iterations){
double d = 0;
for(int j = 1; 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();
$ b $ new Thread(){
@Override
public void run(){
long timestamp = System.currentTimeMillis();
while(true){
System.out.println(Delay+(System.currentTimeMillis() - timestamp));
timestamp = System.currentTimeMillis();
//触发stop-the-world
System.gc();
}
}
} .start();
thread.join();


$ / code $ / pre

结果:

 延迟5 
延迟4
延迟30782
延迟21819
延迟21966
延迟22812
延迟22264
延迟21988

为了增加延迟,只需将参数值更改为 slowpoke(int iterations)函数



以下是有用的诊断命令:


  • -XX:+ PrintGCApplicationStoppedTime 这实际上会将所有安全点的暂停时间报告给GC日志。不幸的是,这个选项的输出缺少时间戳。 在每个安全点后报告原因和计时。


编辑



关于编辑:从用户的角度来看, kill -STOP kill -CONT 与STW具有相同的语义,即应用程序不回应任何请求。但是,这需要访问命令行,并且不会占用资源(CPU,内存)。


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

解决方案

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

这篇关于如何在JVM中强制/重现FullGC?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆