【发布时间】:2020-07-23 05:44:34
【问题描述】:
我看到了这个关于 JVM 内存的有趣问题。这真的很令人困惑。考虑这种情况:不断将一个新对象放入 HashMap 中,而这个对象只有一个 String 字段。应该是OOM,因为我没有覆盖hashcode()和equals(),结果结果不是,JVM一直在做GC。所有对象都被HashMap强引用,为什么没有OOM?
public class FinalTest {
private final String key;
FinalTest(String key){
this.key = key;
}
public void getKey(){
System.out.println( key);
}
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException{
Map<FinalTest,String> map = new HashMap<>();
for(;;){
map.put(new FinalTest("a"),"v");
System.out.println(map.toString());
}
}
}
jconsole 截图:
然后我删除了那个打印命令,结果不一样了……
老一代用法:
曲线在最后一刻下降,因为伊甸空间被清除了。然后看起来进程被阻止(老一代已满)。另外,即使老一代已经满了,也不会产生OOM异常。
为什么这两种情况不同?为什么没有OOM异常?
【问题讨论】:
-
你怎么知道老根已经满了?
-
@gudok 最后一张图片,右下角,Heap usage table的第一列表示使用了多少old gen space。