简体   繁体   English

如何在堆中通过许多StackTraceElement模拟完整的gc

[英]how to emulate full gc by many StackTraceElement in heap

Recently My operation colleague report production environment have many full gc, and influence app response time. 最近我的操作同事报告生产环境有很多全gc,影响app响应时间。 And he supply an image 他提供了一个图像 在此输入图像描述

he especially said StackTraceElement have 85M, and suggests not have these code , eg 他特别说StackTraceElement有85M,并建议没有这些代码,例如

e.printStackTrace();

Now I want to simulate this situation in my local, and I write a test code like below 现在我想在我的本地模拟这种情况,并编写如下的测试代码

public class FullGCByLogTest {
    private static final Logger log = Logger.getLogger(FullGCByLogTest.class);
    public static final byte[] _1M = new byte[1 * 1024 * 1024]; //placeholder purpose

    public static void main(String[] args) throws InterruptedException {
        int nThreads = 1000; // concurrent count
        ExecutorService pool = Executors.newFixedThreadPool(nThreads);
        while (true) {
            final CountDownLatch latch = new CountDownLatch(nThreads);
            for (int i = 0; i < nThreads; i++) {
                pool.submit(new Runnable() {
                    @Override
                    public void run() {
                        latch.countDown();
                        try {
                            latch.await(); // waiting for execute below code concurrently
                        } catch (InterruptedException e1) {
                        }
                        try {
                            int i = 1 / 0;
                            System.out.println(i);
                        } catch (Exception e) {
                            e.printStackTrace();
                            // log.error(e.getMessage(), e);
                        }

                    }
                });
            }
            try {
                Thread.sleep(100); // interval 1s every concurrent calling
            } catch (InterruptedException e) {
            }
       }

    }
}

and I run this class with these vm args 我用这些vm args运行这个类

-Xmx4m -Xms4m -XX:NewSize=1m -XX:MaxNewSize=1m -XX:+PrintGCDetails

then in jvisualvm VisualGC I found old gen is 7 M, but I set max heap is 4m. 然后在jvisualvm VisualGC我发现旧的gen是7 M,但我设置的最大堆是4m。

在此输入图像描述

in addition in heapdump I did not find StackTraceElement. 另外在heapdump中我没有找到StackTraceElement。 So how could I emulate this problem successfully? 那我怎么能成功地模仿这个问题呢?

在此输入图像描述

The StackTraceElement objects are actually created when an exception object is instantiated, and they will be eligible for garbage collection as soon as the exception object is unreachable. StackTraceElement对象实际上是在实例化异常对象时创建的,一旦异常对象无法访问,它们就有资格进行垃圾回收。

I suspect that the real cause for your (apparent) storage leak is that something in your code is saving lots of exception objects. 我怀疑你的(明显的)存储泄漏的真正原因是你的代码中存在大量异常对象。

Calling printStackTrace() does not leak objects. 调用printStackTrace()不会泄漏对象。 Your colleague has misdiagnosed the problem. 你的同事误解了这个问题。 However calling printStackTrace() all over the place is ugly ... and if it happens frequently, that will lead to performance issues. 然而,在整个地方调用printStackTrace()都是丑陋的...如果经常发生,那将导致性能问题。


Your simulation and the results are a red herring, but the probable reason that the heap is bigger than you asked for is that the JVM has "rounded up" to a larger heap size. 您的模拟和结果是一个红色的鲱鱼,但是堆大于您要求的可能原因是JVM已经“舍入”到更大的堆大小。 (4Mb is a miniscule heap size, and impractical for most Java programs.) (4Mb是一个微不足道的堆大小,对大多数Java程序来说都是不切实际的。)


So how could I emulate this problem successfully? 那我怎么能成功地模仿这个问题呢?

Emulation is highly unlikely to tell you anything useful. 仿真极不可能告诉你任何有用的东西。 You need to get hold of a heap dump from the production system and analyze that. 您需要从生产系统中获取堆转储并进行分析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM