-
Bug
-
Resolution: Fixed
-
P3
-
8, 9
-
b129
-
generic
-
generic
FULL PRODUCT VERSION :
C:\tools\Java\jdk1.8.0_45\bin>java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Window 7 64 bit.
A DESCRIPTION OF THE PROBLEM :
Hi Team
We have an issue related to removeAll() implementation of Map in Java 8. As per the current implementation we are iterating the whole data structure to remove a single or no element (If the collection passed doesn't have any element).
Please review the attached sample code and do a JVisual VM profiling.
REGRESSION. Last worked in version 8u73
ADDITIONAL REGRESSION INFORMATION:
C:\tools\Java\jdk1.8.0_45\bin>java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Sample code and JVisualVM profiler snapshot attached.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should work similar to JDK 7 logic. In order to remove a single entry we must not iterate the whole data structure.
public boolean removeAll(Collection<?> c) {
boolean modified = false;
if (size() > c.size()) {
for (Iterator<?> i = c.iterator(); i.hasNext(); )
modified |= remove(i.next());
} else {
for (Iterator<?> i = iterator(); i.hasNext(); ) {
if (c.contains(i.next())) {
i.remove();
modified = true;
}
}
}
return modified;
}
ACTUAL -
In order to remove a single entry we must not iterate the whole data structure.
public final boolean removeAll(Collection<?> c) {
if (c == null) throw new NullPointerException();
boolean modified = false;
for (Iterator<E> it = iterator(); it.hasNext();) {
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class TestConcurrentHashMap {
public static void main(String[] args) {
Map<Integer, Integer> map = new ConcurrentHashMap<Integer, Integer>();
for (int i=0; i<10000000; i++) {
map.put(i, i);
}
List<Integer> oList = new ArrayList<Integer>();
oList.add(9998);
oList.add(9999);
map.keySet().removeAll(oList);
System.out.println(map);
}
}
---------- END SOURCE ----------
C:\tools\Java\jdk1.8.0_45\bin>java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Window 7 64 bit.
A DESCRIPTION OF THE PROBLEM :
Hi Team
We have an issue related to removeAll() implementation of Map in Java 8. As per the current implementation we are iterating the whole data structure to remove a single or no element (If the collection passed doesn't have any element).
Please review the attached sample code and do a JVisual VM profiling.
REGRESSION. Last worked in version 8u73
ADDITIONAL REGRESSION INFORMATION:
C:\tools\Java\jdk1.8.0_45\bin>java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Sample code and JVisualVM profiler snapshot attached.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should work similar to JDK 7 logic. In order to remove a single entry we must not iterate the whole data structure.
public boolean removeAll(Collection<?> c) {
boolean modified = false;
if (size() > c.size()) {
for (Iterator<?> i = c.iterator(); i.hasNext(); )
modified |= remove(i.next());
} else {
for (Iterator<?> i = iterator(); i.hasNext(); ) {
if (c.contains(i.next())) {
i.remove();
modified = true;
}
}
}
return modified;
}
ACTUAL -
In order to remove a single entry we must not iterate the whole data structure.
public final boolean removeAll(Collection<?> c) {
if (c == null) throw new NullPointerException();
boolean modified = false;
for (Iterator<E> it = iterator(); it.hasNext();) {
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class TestConcurrentHashMap {
public static void main(String[] args) {
Map<Integer, Integer> map = new ConcurrentHashMap<Integer, Integer>();
for (int i=0; i<10000000; i++) {
map.put(i, i);
}
List<Integer> oList = new ArrayList<Integer>();
oList.add(9998);
oList.add(9999);
map.keySet().removeAll(oList);
System.out.println(map);
}
}
---------- END SOURCE ----------
- relates to
-
JDK-8163353 NPE in ConcurrentHashMap.removeAll()
-
- Resolved
-