-
Bug
-
Resolution: Fixed
-
P3
-
8u5, 9
-
b88
-
generic
-
generic
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8142171 | emb-9 | Doug Lea | P3 | Resolved | Fixed | team |
JDK-8150780 | 8u102 | Martin Buchholz | P3 | Resolved | Fixed | b02 |
JDK-8224044 | 7u241 | Doug Lea | P3 | Resolved | Fixed | b01 |
JDK-8227026 | 7u231 | Doug Lea | P3 | Resolved | Fixed | b31 |
JDK-8225238 | 7u221 | Doug Lea | P3 | Closed | Fixed | b35 |
JDK-8250722 | openjdk7u | Doug Lea | P3 | Resolved | Fixed | master |
tested on
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
and
java version "1.6.0_37"
Java(TM) SE Runtime Environment (build 1.6.0_37-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
independent of OS
tested on ubuntu :
Linux pc-cap90 3.11.0-24-generic #41-Ubuntu SMP Mon Jun 9 20:36:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
EXTRA RELEVANT SYSTEM CONFIGURATION :
to reproduce easily, small heap is helping (-Xmx4m)
A DESCRIPTION OF THE PROBLEM :
This test case with repeated offer and remove operations on ConcurrentLinkedQueue lead to an OutOfMemory Error.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the following test :
// Quick OutOfMemory with -Xmx4m
public void testOutOfMemory(){
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
String a="a";
String b="b";
queue.offer(a);
for(int i=0;;i++){
if(i % 1024 == 0) {
System.out.println("i = "+i);
}
queue.offer(b);
queue.remove(b);
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No OutOfMemoryError.
ACTUAL -
i = 307200
i = 308224
i = 309248
i = 310272
java.lang.OutOfMemoryError: Java heap space
at java.util.concurrent.ConcurrentLinkedQueue.offer(ConcurrentLinkedQueue.java:274)
at TestConcurrentLinkedQueue16.testOutOfMemory
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public void testOutOfMemory(){
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
String a="a";
String b="b";
queue.offer(a);
for(int i=0;;i++){
if(i % 1024 == 0) {
System.out.println("i = "+i);
}
queue.offer(b);
queue.remove(b);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
When called on the last element of a ConcurrentLinkedQueue with more than 1 element, the remove method nullify the item but the Node object is not unlinked from the list.
After many add/remove the queue structure is : a -> null -> ... -> null -> b
To be garbage collected the Node objects with null item must be unlinked from the list.
They are unlinked only when the queue is iterated or when the head is polled.
The advance() method of the Iterator contains code that skip and unlink nodes with null item :
private E advance() {
lastRet = nextNode;
E x = nextItem;
Node<E> pred, p;
if (nextNode == null) {
p = first();
pred = null;
} else {
pred = nextNode;
p = succ(nextNode);
}
for (;;) {
if (p == null) {
nextNode = null;
nextItem = null;
return x;
}
E item = p.item;
if (item != null) {
nextNode = p;
nextItem = item;
return x;
} else {
// skip over nulls
Node<E> next = succ(p);
if (pred != null && next != null)
pred.casNext(p, next);
p = next;
}
}
}
A fix could be to unlink the Node objects with null items while iterating on the elements in the remove method.
- backported by
-
JDK-8142171 Repeated offer and remove on ConcurrentLinkedQueue lead to an OutOfMemoryError
- Resolved
-
JDK-8150780 Repeated offer and remove on ConcurrentLinkedQueue lead to an OutOfMemoryError
- Resolved
-
JDK-8224044 Repeated offer and remove on ConcurrentLinkedQueue lead to an OutOfMemoryError
- Resolved
-
JDK-8227026 Repeated offer and remove on ConcurrentLinkedQueue lead to an OutOfMemoryError
- Resolved
-
JDK-8250722 Repeated offer and remove on ConcurrentLinkedQueue lead to an OutOfMemoryError
- Resolved
-
JDK-8225238 Repeated offer and remove on ConcurrentLinkedQueue lead to an OutOfMemoryError
- Closed
- duplicates
-
JDK-8134853 Bulk integration of java.util.concurrent and related java.util classes
- Resolved
-
JDK-8137184 Memory leak from ConcurrentLinkedQueue#remove(Object)
- Closed
-
JDK-8137185 ConcurrentLinkedQueue memory leak
- Closed