使用Scala和Tomcat中的TriMap进行潜在的内存泄漏

时间:2013-06-27 07:19:59

标签: scala tomcat scala-collections scala-2.10

我使用包装在对象中的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

我猜这个帖子最终将自己终止,但我想知道是否有某种方法可以杀死它或者我应该不管它?

1 个答案:

答案 0 :(得分:4)

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

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

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

然后,您可以调用localRandom.set(null)以取消对随机数生成器的引用。然后,您还应确保不再使用该TrieMap,否则ThreadLocalRandom会因假设随机数生成器与null不同而中断。

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