简体   繁体   中英

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. And he supply an image 在此输入图像描述

he especially said StackTraceElement have 85M, and suggests not have these code , eg

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

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

在此输入图像描述

in addition in heapdump I did not find 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.

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


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. (4Mb is a miniscule heap size, and impractical for most Java programs.)


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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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