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:
Uwe Schindler 2012-10-04 21:58:26 +00:00
parent 5e144ab7bb
commit 532f82806f
3 changed files with 32 additions and 20 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;