Consider a very large Java VM with a great many threads running a web server.
Now consider a sample of the output generated by jmap -histo
that looks something like this:
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
If you do the division, it turns out we have 25开发者_如何学JAVA6 instances of java.lang.ThreadLocal$ThreadLocalMap$Entry
per thread. Kind of a high number, and more than I'd expect given that most of the ThreadLocals shouldn't be storing a whole lot of values. I don't see that many in Tomcat when I use its ThreadLocal-leak-detection feature.
Any reason these ThreadLocalMaps should be so memory-hungry?
Can you figure out what the values in the thread local map are? Have you poked around with jhat
or equivalent to see what they're referencing?
Could be running into this bug:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6625723
The problem seems to be the actual number of thread locals, not the values that they contain.
I suspect that you might be using ThreadLocal incorrectly. The ThreadLocal
object should be created (once) and assigned to a static
variable, as shown in the example in the javadoc.
If you create the ThreadLocal
object in the initializer of a non-static variable, then each time the variable declaration is executed you get a new thread local. If you combine this with thread pooling, then you'll get lots of useless thread local map entries.
精彩评论