I have a simple example. The example loads an ArrayList<Integer> from a file f containing 10000000 random integers.
doLog("Test 2");
{
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
List<Integer> l = (List<Integer>) ois.readObject();
ois.close();
fis.close();
doLog("Test 2.1");
//l = null;
doLog("Test 2.2");
}
doLog("Test 2.3");
System.gc();
doLog("Test 2.4");
When I have l = null, I get this log:
Test 2 Used Mem = 492 KB Total Mem = 123 MB
Test 2.1 Used Mem = 44 MB Total Mem = 123 MB
Test 2.2 Used Mem = 44 MB Total Mem = 123 MB
Test 2.3 Used Mem = 44 MB Total Mem = 123 MB
Test 2.4 Used Mem = 493 KB Total Mem = 123 MB
But when I remove it, I get this log instead.
Test 2 Used Mem = 492 KB Total Mem = 123 MB
Test 2.1 Used Mem = 44 MB Total Mem = 123 MB
Test 2.2 Used Mem = 44 MB Total Mem = 123 MB
Test 2.3 Used Mem = 44 MB Total Mem = 123 MB
Test 2.4 Used Mem = 44 MB Total Mem = 123 MB
Used Memory is calculated by: runTime.totalMemory() - runTime.freeMemory()
Question: In case where l = null; is present, is there a memory leak?
l is inaccessible, so why can’t it be freed?
There is no memory leak in the above code.
As soon as you leave the code block enclosed in
{}, the variablelfalls out of scope, and theListis a candidate for garbage collection, regardless of if you set it tonullfirst or not.However, after the code block and until the return of the method, the
Listis in a state called invisible. While this is true, the JVM is unlikely to automatically null out the reference and collect theList‘s memory. Therefore, explicitly settingl = nullcan help the JVM collect the memory before you do your memory calculations. Otherwise, it will happen automatically when the method returns.You will probably get different results for different runs of your code, since you never know exactly when the garbage collector will run. You can suggest that you think it should run using
System.gc()(and it might even collect the invisibleListeven without settingl = null), but there are no promises. It is stated in the javadoc for System.gc():