aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSem Mulder <sem.mulder@site2mobile.com>2015-10-27 07:55:10 +0000
committerSean Owen <sowen@cloudera.com>2015-10-27 07:55:10 +0000
commitfeb8d6a44fbfc31a880aaaac0cfcaadc91786073 (patch)
treee8d3d40f3364a937538c7d02beab30ecae2ae598
parentd77d198fcc7c532a699f062a3e3877a7679809da (diff)
downloadspark-feb8d6a44fbfc31a880aaaac0cfcaadc91786073.tar.gz
spark-feb8d6a44fbfc31a880aaaac0cfcaadc91786073.tar.bz2
spark-feb8d6a44fbfc31a880aaaac0cfcaadc91786073.zip
[SPARK-11276][CORE] SizeEstimator prevents class unloading
The SizeEstimator keeps a cache of ClassInfos but this cache uses Class objects as keys. Which results in strong references to the Class objects. If these classes are dynamically created this prevents the corresponding ClassLoader from being GCed. Leading to PermGen exhaustion. We use a Map with WeakKeys to prevent this issue. Author: Sem Mulder <sem.mulder@site2mobile.com> Closes #9244 from SemMulder/fix-sizeestimator-classunloading.
-rw-r--r--core/src/main/scala/org/apache/spark/util/SizeEstimator.scala6
1 files changed, 4 insertions, 2 deletions
diff --git a/core/src/main/scala/org/apache/spark/util/SizeEstimator.scala b/core/src/main/scala/org/apache/spark/util/SizeEstimator.scala
index 14b1f2a17e..23ee4eff08 100644
--- a/core/src/main/scala/org/apache/spark/util/SizeEstimator.scala
+++ b/core/src/main/scala/org/apache/spark/util/SizeEstimator.scala
@@ -17,6 +17,8 @@
package org.apache.spark.util
+import com.google.common.collect.MapMaker
+
import java.lang.management.ManagementFactory
import java.lang.reflect.{Field, Modifier}
import java.util.{IdentityHashMap, Random}
@@ -29,7 +31,6 @@ import org.apache.spark.Logging
import org.apache.spark.annotation.DeveloperApi
import org.apache.spark.util.collection.OpenHashSet
-
/**
* :: DeveloperApi ::
* Estimates the sizes of Java objects (number of bytes of memory they occupy), for use in
@@ -73,7 +74,8 @@ object SizeEstimator extends Logging {
private val ALIGN_SIZE = 8
// A cache of ClassInfo objects for each class
- private val classInfos = new ConcurrentHashMap[Class[_], ClassInfo]
+ // We use weakKeys to allow GC of dynamically created classes
+ private val classInfos = new MapMaker().weakKeys().makeMap[Class[_], ClassInfo]()
// Object and pointer sizes are arch dependent
private var is64bit = false