One of our programs is sometimes getting an OutOfMemory
error on one user\'s machine, but of course not when I\'m testing it. I just ran it with JProfiler (on
Collections was already mentioned. Another hard-to-find location is if you use multiple ClassLoaders, as the old classloader may be unable to be garbage collected until all references have gone.
Also check statics - these are nasty. Logging frameworks can keep things open which may keep references in custom appenders.
Did you resolve the problem?
I've used the Yourkit Java profiler(http://www.yourkit.com) for performance optimizations on java 1.5. It has a section on how to work on memory leaks. I find it useful.
http://www.yourkit.com/docs/75/help/performance_problems/memory_leaks/index.jsp
You can get a 15 day eval : http://www.yourkit.com/download/yjp-7.5.7.exe
BR,
~A
Some suggestions:
One obvious candidate is objects with finalisers. They can linger while their finalize method is called. They need to be collected, then finalised (usually with just a single finaliser thread) and then collected again.
Also be aware that you can get an OOME because the gc failed to collect enough memory, despite there actually being enough for the object request to be created. Otherwise performance would grind into the ground.
I just read an article on this, but I'm sorry I can't remember where. I think it might have been in the book "Effective Java". If I find the reference, I'll update my answer.
The two important lessons it outlined are:
1) Final methods tell the gc what to do when it culls the object, but it doesn't ask it to do so, nor is there a way to demand that it does.
2) The modern-day equivalent of the "memory leak" in unmanaged memory environments, is the forgotten references. If you don't set all references to an object to null when you're done with it, the object will never be culled. This is most important when implementing your own kind of Collection, or your own wrapper that manages a Collection. If you have a pool or a stack or a queue, and you don't set the bucket to null when you "remove" an object from the collection, the bucket that object was in will keep that object alive until that bucket is set to refer to another object.
disclaimer: I know other answers mentioned this, but I'm trying to offer more detail.