As I've found somewhere on web, following items can lead to memory leaks. For example:
- ResultSets and Statement objects
- DataLists
- Collections
- Static variables and classes
- Singletons
- HttpSession and HttpRequest
Managed beans in my JSF application are mostly @ViewScoped
, so I thought that after leaving the view, GC has enough informations to release datalists, objects, and so on. But it hasn't or not completelly:
I'm just closing hibernate sessions manually (using finally), but that's all. The rest of things I've expected from GC.
Could you tell me,
- how to find which concrete objects are staying in memory?
- how to release objects after leaving a view manually? something like destructor..?
- what are the best practices in handle memory leaks?
First of all IMHO this is NOT real memmory leak. GC releases memmory from time to time. Maybe you should show us report from longer time. Maybe sth is holding objects too long. To look at references, you can use JProfiler like here. Try Eclipse Memory Analyzer automatic reports too. I think you should try tuning Garbage Collection. And for finding memmory leak look at this response How to find a Java Memory Leak
We, in our project, have used yourkit ( http://www.yourkit.com/eap/index.jsp ) profiler. I found the user interface very friendly.
You can connect to your web application and find out the object growth and how the growth rate is.
The profiler helps you trace each object to the the origin. You can hence figure out the parent object that is holding a reference to the object that is not garbage collecting.
Watch out for:
When you have a loaded java collection and are done with it, assign
collectionObject=null
. we noticed that even though the list went out of scope , it was not getting garbage collected until it was set to null.Objects being created in a loop.
objects being referenced across classes. these objects tend to stay in the system until all the references are released.
String concatenations(
String a = b+s
) are very very costly !Overloading HTTP Session
JHat, Eclipse MAT can be helpful. Even, JConsole gives enough clues about memory leaks -- or at least what's hogging all of your RAM.
You should use one of available java profilers. There are a lot. All profilers allow to store snapshot and compare snapshots. So, you should store snapshot in the beginning, then perform some scenario with your application, then store snapshot again and compare. You will get all objects that cannot be removed by GC and their references. Then try to analyze who is holding references to these objects and how to fix the bug.