Bac*_*chT 17 java memory-leaks
我有一个简单的例子.该示例ArrayList<Integer>从f包含10000000个随机整数的文件加载an .
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");
Run Code Online (Sandbox Code Playgroud)
当我有l = null,我得到这个日志:
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
Run Code Online (Sandbox Code Playgroud)
但是当我删除它时,我得到了这个日志.
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
Run Code Online (Sandbox Code Playgroud)
Used Memory 计算方法是: runTime.totalMemory() - runTime.freeMemory()
问题:如果l = null;存在,是否存在内存泄漏?
l是无法进入的,为什么它不能被释放?
Kep*_*pil 28
上面的代码中没有内存泄漏.
一旦你将代码块放在其中{},变量l就会超出范围,并且它List是垃圾收集的候选者,无论你是否将其设置为nullfirst.
但是,在代码块之后直到返回方法,List处于一种称为不可见的状态.虽然这是事实,但JVM不太可能自动使引用无效并收集List内存.因此,显式设置l = null可以帮助JVM在进行内存计算之前收集内存.否则,它将在方法返回时自动发生.
对于不同的代码运行,您可能会得到不同的结果,因为您永远不知道垃圾收集器何时运行.你可以建议你认为它应该运行System.gc()(甚至可以在List没有设置的情况下收集隐形l = null),但是没有任何承诺.它在System.gc()的javadoc中声明:
调用gc方法表明Java虚拟机花费了大量精力来回收未使用的对象,以使其当前占用的内存可用于快速重用.当控制从方法调用返回时,Java虚拟机已尽最大努力从所有丢弃的对象中回收空间.
| 归档时间: |
|
| 查看次数: |
795 次 |
| 最近记录: |