考虑一个非常大的Java VM,它有很多运行Web服务器的线程。
现在考虑一下jmap -histo
生成的输出样本,如下所示:
4: 5989163 191653216 java.lang.ThreadLocal$ThreadLocalMap$Entry
10: 46786 49012000 [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;
86: 23384 2619008 java.lang.Thread
144: 46750 1122000 java.lang.ThreadLocal$ThreadLocalMap
如果你进行除法,我们发现每个线程有256个java.lang.ThreadLocal$ThreadLocalMap$Entry
个实例。鉴于大多数ThreadLocals不应存储大量值,因此数字很高,而且超出了我的预期。当我使用ThreadLocal泄漏检测功能时,我在Tomcat中看不到那么多。
这些ThreadLocalMaps应该如此占用大量内存?
答案 0 :(得分:1)
你能弄清楚线程局部地图中的值是什么吗?您是否使用jhat
或等效内容来查看他们引用的内容?
答案 1 :(得分:1)
答案 2 :(得分:0)
问题似乎是线程本地的实际数量,而不是它们包含的值。
我怀疑您可能错误地使用了ThreadLocal。应创建ThreadLocal
对象(一次)并将其分配给static
变量,如the javadoc中的示例所示。
如果在非静态变量的初始值设定项中创建ThreadLocal
对象,则每次执行变量声明时,都会获得一个新的本地线程。如果将它与线程池结合使用,那么你将获得许多无用的线程本地映射条目。