1

我正在使用scala.collection.concurrent.TriMap包装在一个对象中来存储远程获取的配置值。

object persistentMemoryMap {
  val storage: TrieMap[String, CacheEntry] = TrieMap[String, CacheEntry]()
}

它工作得很好,但我注意到当 Tomcat 关闭时,它会记录一些关于潜在内存泄漏的警告消息

2013-jun-27 08:58:22 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
ALLVARLIG: The web application [] created a ThreadLocal with key of type [scala.concurrent.forkjoin.ThreadLocalRandom$1] (value [scala.concurrent.forkjoin.ThreadLocalRandom$1@5d529976]) and a value of type [scala.concurrent.forkjoin.ThreadLocalRandom] (value [scala.concurrent.forkjoin.ThreadLocalRandom@59d941d7]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak

我猜这个线程最终会自行终止,但我想知道是否有某种方法可以杀死它,或者我应该不理会它吗?

4

1 回答 1

4

每个scala.concurrent.forkjoin.ThreadLocalRandom线程只创建一次 ' 值。除了该线程使用的随机值生成器之外,它不保存对对象的任何引用——它消耗的内存具有固定大小。一旦线程被垃圾收集,它的线程本地随机值也将被收集——你应该让 GC 完成它的工作。

您仍然可以通过使用 Java 反射来删除类中静态字段上的修饰符来手动删除private它:localRandomThreadLocalRandom

https://github.com/scala/scala/blob/master/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java#L62

然后,您可以调用localRandom.set(null)以取消对随机数生成器的引用。然后,您还应该确保TrieMap不再从该线程中使用 ,否则ThreadLocalRandom将通过假设随机数生成器不同于null.

对我来说似乎很老套,我认为你应该坚持让 GC 收集线程本地值。

于 2013-06-27T08:12:16.813 回答