I read from a book that the following code will cause memory leak,and the book tells that we should remove the code queue.add(new Object()); and it will not cause memory leak. but I don't know why. Why?
import com.google.common.base.Stopwatch;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
public class ConcurrentLinkedQueueMemLeak
{
public static void main(String[] args) throws InterruptedException
{
ConcurrentLinkedQueue<Object> queue =
new ConcurrentLinkedQueue<>();
queue.add(new Object()); // ① 这一行代码会导致内存泄漏
Object object = new Object();
int loops = 0;
// 休眠10秒,方便打开JDK诊断工具,监控执行前后的内存变化
TimeUnit.SECONDS.sleep(10);
Stopwatch watch = Stopwatch.createStarted();
while (true)
{
// 每执行10000次进行一次耗时统计,并且输出
if (loops % 10000 == 0 && loops != 0)
{
long elapsedMs = watch.stop()
.elapsed(TimeUnit.MILLISECONDS);
System.out.printf("loops=%d duration=%d MS%n", loops, elapsedMs);
watch.reset().start();
}
queue.add(object);
// ② remove方法删除object
queue.remove(object);
++loops;
}
}
}
before remove the code queue.add(new Object()):
loops=10000 duration=588 MS
loops=20000 duration=1881 MS
loops=30000 duration=3175 MS
loops=40000 duration=3452 MS
loops=50000 duration=3784 MS
loops=60000 duration=4424 MS
loops=70000 duration=4761 MS
loops=80000 duration=5733 MS
after remove the code queue.add(new Object()):
loops=363590000 duration=0 MS
loops=363600000 duration=0 MS
loops=363610000 duration=0 MS
loops=363620000 duration=0 MS
loops=363630000 duration=1 MS
Yes. This will cause memory leak issue.
Explanation :
queue.add(new Object())adds a new object to theConcurrentLinkedQueue, which means queue will hold the reference to that object until it is removed.This might cause the
ConcurrentLinkedQueueto keep the reference to the object indefinitely, even when the object is no longer needed, causing memory leak.Note : Make sure that the object is removed from the queue after it is no longer needed.