如何检查是否离开的ConcurrentLinkedQueue垃圾(解引用实例)的GC?(How do

2019-10-20 07:30发布

我使用的是一堆ConcurrentLinkedQueue在我的应用程序S和GC开销是巨大的。 如何检查ConcurrentLinkedQueue是罪魁祸首? 有没有在Java中的标准方法天寒内存分配/释放这些数据结构?

Answer 1:

做到这一点的方法之一是写一个简单的测试程序,并与运行-verbose:gc JVM选项。 例如,代码:

import java.util.concurrent.ConcurrentLinkedQueue;

public class TestGC {

    public static void main(String[] args) throws Exception {

        final ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();

        String[] strings = new String[1024];

        for(int i = 0; i < strings.length; i++) {
            strings[i] = "string" + i;
        }

        System.gc();
        Thread.sleep(1000);

        System.out.println("Starting...");

        while(true) {
            for(int i = 0; i < strings.length; i++) queue.offer(strings[i]);
            for(int i = 0; i < strings.length; i++) queue.poll();
        }
    }
}

产生的输出:

$ java -verbose:gc TestGC
[GC 1352K->560K(62976K), 0.0015210 secs]
[Full GC 560K->440K(62976K), 0.0118410 secs]
Starting...
[GC 17336K->536K(62976K), 0.0005950 secs]
[GC 17432K->536K(62976K), 0.0006130 secs]
[GC 17432K->504K(62976K), 0.0005830 secs]
[GC 17400K->504K(62976K), 0.0010940 secs]
[GC 17400K->536K(77824K), 0.0006540 secs]
[GC 34328K->504K(79360K), 0.0008970 secs]
[GC 35320K->520K(111616K), 0.0008920 secs]
[GC 68104K->520K(111616K), 0.0009930 secs]
[GC 68104K->520K(152576K), 0.0006350 secs]
[GC 109064K->520K(147968K), 0.0007740 secs]
(keeps going forever)

现在,如果你想知道究竟谁是可以使用分析工具的罪魁祸首。 我写这个内存采样 ,你可以在你的代码插入到正在创建的内容源代码行的情况下,很快找到了。 所以你也是:

MemorySampler.start();
for(int i = 0; i < strings.length; i++) queue.offer(strings[i]);
for(int i = 0; i < strings.length; i++) queue.poll();
MemorySampler.end();
if (MemorySampler.wasMemoryAllocated()) MemorySampler.printSituation();

当你运行你:

Starting...
Memory allocated on last pass: 24576
Memory allocated total: 24576

Stack Trace:
    java.util.concurrent.ConcurrentLinkedQueue.offer(ConcurrentLinkedQueue.java:327)
    TestGC.main(TestGC2.java:25)

从这里可以看到该行的327 ConcurrentLinkedQueue泄漏情况的GC,换句话说,它不是集中他们:

public boolean offer(E e) {
    checkNotNull(e);
    final Node<E> newNode = new Node<E>(e);

    for (Node<E> t = tail, p = t;;) {


Answer 2:

尝试使用VisualVM的 ,官方的(?)Java剖析。 玩的是一点点。 您可以分析的过程和你运行任何Java程序的内存。



文章来源: How do I check if ConcurrentLinkedQueue leaves garbage (dereferenced instances) for the GC?