2013-06-27 77 views
1

我使用包裝在對象中的scala.collection.concurrent.TriMap來存儲遠程獲取的配置值。在Scala和Tomcat中使用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 [[email protected]]) and a value of type [scala.concurrent.forkjoin.ThreadLocalRandom] (value [[email protected]]) 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

scala.concurrent.forkjoin.ThreadLocalRandom的值每個線程只創建一次。它不包含除該線程使用的隨機值生成器之外的對象的任何引用 - 它消耗的內存具有固定的大小。一旦線程被垃圾收集,它的線程本地隨機值也將被收集 - 你應該讓GC完成它的工作。

您仍然可以通過使用Java反射,以消除靜電場localRandomprivate修改在ThreadLocalRandom類手動刪除它:

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

然後,您可以撥打localRandom.set(null)來清零參考隨機數發生器。您還應該確保TrieMap不再從該線程使用,否則ThreadLocalRandom將通過假設隨機數生成器不同於null而中斷。

對我來說似乎很難,我想你應該堅持讓GC收集線程本地值。