mirror of https://github.com/apache/lucene.git
LUCENE-4459: Improve WeakIdentityMap.keyIterator() to remove GCed keys from backing map early instead of waiting for reap(). This makes test failures in TestWeakIdentityMap disappear, too.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1394291 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5e144ab7bb
commit
532f82806f
|
@ -43,6 +43,11 @@ Optimizations
|
|||
into the skipdata. You need to reindex any indexes created with
|
||||
this experimental codec. (Robert Muir)
|
||||
|
||||
* LUCENE-4459: Improve WeakIdentityMap.keyIterator() to remove GCed keys
|
||||
from backing map early instead of waiting for reap(). This makes test
|
||||
failures in TestWeakIdentityMap disappear, too.
|
||||
(Uwe Schindler, Mike McCandless, Robert Muir)
|
||||
|
||||
Build
|
||||
|
||||
* LUCENE-4451: Memory leak per unique thread caused by
|
||||
|
|
|
@ -133,22 +133,22 @@ public final class WeakIdentityMap<K,V> {
|
|||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return nextIsSet ? true : setNext();
|
||||
return nextIsSet || setNext();
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("unchecked")
|
||||
public K next() {
|
||||
if (nextIsSet || setNext()) {
|
||||
try {
|
||||
assert nextIsSet;
|
||||
return (K) next;
|
||||
} finally {
|
||||
// release strong reference and invalidate current value:
|
||||
nextIsSet = false;
|
||||
next = null;
|
||||
}
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
assert nextIsSet;
|
||||
try {
|
||||
return (K) next;
|
||||
} finally {
|
||||
// release strong reference and invalidate current value:
|
||||
nextIsSet = false;
|
||||
next = null;
|
||||
}
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -161,14 +161,15 @@ public final class WeakIdentityMap<K,V> {
|
|||
while (iterator.hasNext()) {
|
||||
next = iterator.next().get();
|
||||
if (next == null) {
|
||||
// already garbage collected!
|
||||
continue;
|
||||
// the key was already GCed, we can remove it from backing map:
|
||||
iterator.remove();
|
||||
} else {
|
||||
// unfold "null" special value:
|
||||
if (next == NULL) {
|
||||
next = null;
|
||||
}
|
||||
return nextIsSet = true;
|
||||
}
|
||||
// unfold "null" special value
|
||||
if (next == NULL) {
|
||||
next = null;
|
||||
}
|
||||
return nextIsSet = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -122,13 +122,16 @@ public class TestWeakIdentityMap extends LuceneTestCase {
|
|||
for (int i = 0; size > 0 && i < 10; i++) try {
|
||||
System.runFinalization();
|
||||
System.gc();
|
||||
int newSize = map.size();
|
||||
assertTrue("previousSize("+size+")>=newSize("+newSize+")", size >= newSize);
|
||||
size = newSize;
|
||||
Thread.sleep(100L);
|
||||
c = 0;
|
||||
for (Iterator<String> it = map.keyIterator(); it.hasNext();) {
|
||||
assertNotNull(it.next());
|
||||
c++;
|
||||
}
|
||||
final int newSize = map.size();
|
||||
newSize = map.size();
|
||||
assertTrue("previousSize("+size+")>=iteratorSize("+c+")", size >= c);
|
||||
assertTrue("iteratorSize("+c+")>=newSize("+newSize+")", c >= newSize);
|
||||
size = newSize;
|
||||
|
@ -223,13 +226,16 @@ public class TestWeakIdentityMap extends LuceneTestCase {
|
|||
for (int i = 0; size > 0 && i < 10; i++) try {
|
||||
System.runFinalization();
|
||||
System.gc();
|
||||
int newSize = map.size();
|
||||
assertTrue("previousSize("+size+")>=newSize("+newSize+")", size >= newSize);
|
||||
size = newSize;
|
||||
Thread.sleep(100L);
|
||||
int c = 0;
|
||||
for (Iterator<Object> it = map.keyIterator(); it.hasNext();) {
|
||||
assertNotNull(it.next());
|
||||
c++;
|
||||
}
|
||||
final int newSize = map.size();
|
||||
newSize = map.size();
|
||||
assertTrue("previousSize("+size+")>=iteratorSize("+c+")", size >= c);
|
||||
assertTrue("iteratorSize("+c+")>=newSize("+newSize+")", c >= newSize);
|
||||
size = newSize;
|
||||
|
|
Loading…
Reference in New Issue