From b76471c5dfd8ffc9410ac522404026bee938dfd6 Mon Sep 17 00:00:00 2001 From: Sean Owen Date: Sun, 29 Aug 2021 09:29:23 -0700 Subject: [PATCH] [SPARK-36603][CORE] Use WeakReference not SoftReference in LevelDB ### What changes were proposed in this pull request? Use WeakReference not SoftReference in LevelDB ### Why are the changes needed? (See discussion at https://github.com/apache/spark/pull/28769#issuecomment-906722390 ) "The soft reference to iterator introduced in this pr unfortunately ended up causing iterators to not be closed when they go out of scope (which would have happened earlier in the finalize) This is because java is more conservative in cleaning up SoftReference's. The net result was we ended up having 50k files for SHS while typically they get compacted away to 200 odd files. Changing from SoftReference to WeakReference should make it much more aggresive in cleanup and prevent the issue - which we observed in a 3.1 SHS" ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? Existing tests Closes #33859 from srowen/SPARK-36603. Authored-by: Sean Owen Signed-off-by: Dongjoon Hyun (cherry picked from commit 89e907f76c7143ac595c71d4ac3eed8440a3c148) Signed-off-by: Dongjoon Hyun --- .../java/org/apache/spark/util/kvstore/LevelDB.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/common/kvstore/src/main/java/org/apache/spark/util/kvstore/LevelDB.java b/common/kvstore/src/main/java/org/apache/spark/util/kvstore/LevelDB.java index 121dfbd4f6..6b28373a48 100644 --- a/common/kvstore/src/main/java/org/apache/spark/util/kvstore/LevelDB.java +++ b/common/kvstore/src/main/java/org/apache/spark/util/kvstore/LevelDB.java @@ -19,7 +19,8 @@ package org.apache.spark.util.kvstore; import java.io.File; import java.io.IOException; -import java.lang.ref.SoftReference; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; @@ -69,10 +70,10 @@ public class LevelDB implements KVStore { /** * Trying to close a JNI LevelDB handle with a closed DB causes JVM crashes. This is used to - * ensure that all iterators are correctly closed before LevelDB is closed. Use soft reference + * ensure that all iterators are correctly closed before LevelDB is closed. Use weak references * to ensure that the iterator can be GCed, when it is only referenced here. */ - private final ConcurrentLinkedQueue>> iteratorTracker; + private final ConcurrentLinkedQueue>> iteratorTracker; public LevelDB(File path) throws Exception { this(path, new KVStoreSerializer()); @@ -250,7 +251,7 @@ public class LevelDB implements KVStore { public Iterator iterator() { try { LevelDBIterator it = new LevelDBIterator<>(type, LevelDB.this, this); - iteratorTracker.add(new SoftReference<>(it)); + iteratorTracker.add(new WeakReference<>(it)); return it; } catch (Exception e) { throw Throwables.propagate(e); @@ -301,7 +302,7 @@ public class LevelDB implements KVStore { try { if (iteratorTracker != null) { - for (SoftReference> ref: iteratorTracker) { + for (Reference> ref: iteratorTracker) { LevelDBIterator it = ref.get(); if (it != null) { it.close();