diff options
author | Tim Harper <timcharper@gmail.com> | 2014-10-29 00:15:43 -0600 |
---|---|---|
committer | Tim Harper <timcharper@gmail.com> | 2014-11-22 22:22:26 -0700 |
commit | d367c5f925e7055e9ee5b4071328e92cf48ce0ed (patch) | |
tree | 91c45f1147b28992209ae47ee0394a08e3370c0d /src | |
parent | c4df20d29a8d15ef23cf0d10fad56da0791bbbf6 (diff) | |
download | scala-d367c5f925e7055e9ee5b4071328e92cf48ce0ed.tar.gz scala-d367c5f925e7055e9ee5b4071328e92cf48ce0ed.tar.bz2 scala-d367c5f925e7055e9ee5b4071328e92cf48ce0ed.zip |
Fixes memory leak when using reflection
References to Threads would be retained long after their termination if
reflection is used in them. This led to a steady, long memory leak in
applications using reflection in thread pools.
Diffstat (limited to 'src')
-rw-r--r-- | src/reflect/scala/reflect/runtime/ThreadLocalStorage.scala | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/src/reflect/scala/reflect/runtime/ThreadLocalStorage.scala b/src/reflect/scala/reflect/runtime/ThreadLocalStorage.scala index 5edc051461..586b8a5257 100644 --- a/src/reflect/scala/reflect/runtime/ThreadLocalStorage.scala +++ b/src/reflect/scala/reflect/runtime/ThreadLocalStorage.scala @@ -11,12 +11,16 @@ private[reflect] trait ThreadLocalStorage { trait ThreadLocalStorage[T] { def get: T; def set(newValue: T): Unit } private class MyThreadLocalStorage[T](initialValue: => T) extends ThreadLocalStorage[T] { // TODO: how do we use org.cliffc.high_scale_lib.NonBlockingHashMap here? - val values = new java.util.concurrent.ConcurrentHashMap[Thread, T]() + // (we would need a version that uses weak keys) + private val values = java.util.Collections.synchronizedMap(new java.util.WeakHashMap[Thread, T]()) def get: T = { if (values containsKey currentThread) values.get(currentThread) else { val value = initialValue - values.putIfAbsent(currentThread, value) + // since the key is currentThread, and `values` is private, it + // would be impossible for a value to have been set after the + // above containsKey check. `putIfAbsent` is not necessary. + values.put(currentThread, value) value } } |