FULL PRODUCT VERSION :
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux Tile440 3.19.0-28-generic #30-Ubuntu SMP Mon Aug 31 15:52:51 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
when removing the last object from a ConcurrentLinkedQueue, the item is nulled but the holder is never unlinked from the list.
Thus the attached program results in a forever increasing list of null item entries. This is slow and a memory leak.
This was found and reported by Max Urech in https://bugs.eclipse.org/bugs/show_bug.cgi?id=477817
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
If you run the attached test case you will see each iteration takes longer and longer. Inspection with a debugger reveals the link list growing with null entries.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The node should have both its item nulled and be removed from the list by having the pred node's next pointer nulled. The list should not grow forever.
ACTUAL -
The remove code both nulls the item value and then attempts to delink the pred next node pointer. However, if the current node next pointer is null (ie the last item), then the pred node next is not nulled. Thus the list grows forever!
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.concurrent.ConcurrentLinkedQueue;
public class TestLeak
{
public static void main(String[] args)
{
ConcurrentLinkedQueue<Object> queue=new ConcurrentLinkedQueue<>();
queue.add(new Object()); //Required for the leak to appear.
Object object=new Object();
int loops=0;
Runtime rt=Runtime.getRuntime();
long last=System.currentTimeMillis();
while(true)
{
if(loops%10000==0)
{
long now=System.currentTimeMillis();
long duration=now-last;
last=now;
System.err.printf("duration=%d q.size=%d memory max=%d free=%d total=%d%n",duration,queue.size(),rt.maxMemory(),rt.freeMemory(),rt.totalMemory());
}
queue.add(object);
queue.remove(object);
++loops;
}
}
}
---------- END SOURCE ----------
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux Tile440 3.19.0-28-generic #30-Ubuntu SMP Mon Aug 31 15:52:51 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
when removing the last object from a ConcurrentLinkedQueue, the item is nulled but the holder is never unlinked from the list.
Thus the attached program results in a forever increasing list of null item entries. This is slow and a memory leak.
This was found and reported by Max Urech in https://bugs.eclipse.org/bugs/show_bug.cgi?id=477817
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
If you run the attached test case you will see each iteration takes longer and longer. Inspection with a debugger reveals the link list growing with null entries.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The node should have both its item nulled and be removed from the list by having the pred node's next pointer nulled. The list should not grow forever.
ACTUAL -
The remove code both nulls the item value and then attempts to delink the pred next node pointer. However, if the current node next pointer is null (ie the last item), then the pred node next is not nulled. Thus the list grows forever!
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.concurrent.ConcurrentLinkedQueue;
public class TestLeak
{
public static void main(String[] args)
{
ConcurrentLinkedQueue<Object> queue=new ConcurrentLinkedQueue<>();
queue.add(new Object()); //Required for the leak to appear.
Object object=new Object();
int loops=0;
Runtime rt=Runtime.getRuntime();
long last=System.currentTimeMillis();
while(true)
{
if(loops%10000==0)
{
long now=System.currentTimeMillis();
long duration=now-last;
last=now;
System.err.printf("duration=%d q.size=%d memory max=%d free=%d total=%d%n",duration,queue.size(),rt.maxMemory(),rt.freeMemory(),rt.totalMemory());
}
queue.add(object);
queue.remove(object);
++loops;
}
}
}
---------- END SOURCE ----------
- duplicates
-
JDK-8054446 Repeated offer and remove on ConcurrentLinkedQueue lead to an OutOfMemoryError
- Resolved
-
JDK-8137185 ConcurrentLinkedQueue memory leak
- Closed