scala - 在 Scala 和 Tomcat 中使用 TriMap 的潜在内存泄漏

标签 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

我猜这个线程最终会自行终止,但我想知道是否有某种方法可以终止它,还是我应该让它一个人呆着?

最佳答案

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

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

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

然后您可以调用 localRandom.set(null) 来清空对随机数生成器的引用。然后,您还应确保该线程不再使用 TrieMap,否则 ThreadLocalRandom 将因假设随机数生成器不同于 null 而中断>.

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

关于scala - 在 Scala 和 Tomcat 中使用 TriMap 的潜在内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17336966/

相关文章:

java - JAX-RS REST 在 WildFly 工作,但不在 Tomcat 工作

Scala的collection的sliding()在窗口大小大于step时不一致

scala - 列表值的函数计算

java - 将 XML 从 JSF textarea 传递到 Bean

linux - 无法在 Eclipse Juno 上配置 Tomcat 7

scala - 如何通过键对元组列表求和

java - 如何在 Java 测试文件中使用 ScalaTest?

具有更高级类型的 Scala 类型投影

scala - 理解类型投影

scala - 如何从 Scala 函数返回 Unit?