There are two things that will cause a Thread to be not garbage collected.
Any thread that is still alive will not be garbage collected. A thread is alive until the run
method called by Thread.start()
exits, either normally or by throwing an exception. Once this happens (and the thread's uncaught exception handler has finished), the thread is dead.
Any live reference to the Thread object for a thread will prevent it from being garbage collected. The live reference could be in your code, or if you are using thread pools, they could be part of the pool data structures.
The memory of my java process keeps growing but yet the heap does not increase.
That would be because each thread has a large (e.g. 1Mb) stack segment that is not allocated in the Java heap.
A thread's stack segment is only allocated when the thread is started, and released as soon as the thread terminates. The same also applies (I think) to the thread's thread-local map. A Thread object that is not "alive" doesn't use much memory at all.
So to sum it up. You appear to have lots of live threads. They won't be garbage collected as long as they are alive, and the only way to make them release their memory is to cause them to die ... somehow.
To reduce memory usage, you to need to do one or more of:
- Look at the thread code (the
run()
methods, etc) to figure out why they are still hanging around.
- Reduce the size of the thread stacks. (In theory, you can go as low as 64K ...)
- Redesign your app so that it doesn't create thousands of threads. (Thread pools and some kind of work queue is one possible approach.)