views:

21

answers:

3

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 256 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?

+1  A: 

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?

andersoj
A: 

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.

Stephen C
A: 

Could be running into this bug:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6625723

sehugg