我在我的应用程序中使用了一堆ConcurrentLinkedQueue
,并且GC开销很大。如何检查ConcurrentLinkedQueue
是否是罪魁祸首? Java中是否有标准方法来分析这些数据结构以进行内存分配/释放?
答案 0 :(得分: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)
现在,如果您想确切地知道谁是罪魁祸首,您可以使用分析工具。我写了this memory sampler,您可以插入代码以快速找出正在创建实例的源代码行。所以你这样做:
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)
从那里可以看到ConcurrentLinkedQueue
的第327行正在泄漏GC的实例,换句话说,它没有汇集它们:
public boolean offer(E e) {
checkNotNull(e);
final Node<E> newNode = new Node<E>(e);
for (Node<E> t = tail, p = t;;) {
答案 1 :(得分:0)
尝试使用官方(?)java探查器VisualVM。稍微玩一下。您可以分析您正在运行的任何Java程序的进程和内存。