gpt4 book ai didi

java - 尽管使用了WeakHashMap,但仍发生OutOfMemoryException

转载 作者:行者123 更新时间:2023-12-01 09:35:08 26 4
gpt4 key购买 nike

如果不调用System.gc(),则系统将引发OutOfMemoryException。我不知道为什么我需要显式调用System.gc(); JVM应该自己调用gc(),对吗?请指教。

以下是我的测试代码:

public static void main(String[] args) throws InterruptedException {
WeakHashMap<String, int[]> hm = new WeakHashMap<>();
int i = 0;
while(true) {
Thread.sleep(1000);
i++;
String key = new String(new Integer(i).toString());
System.out.println(String.format("add new element %d", i));
hm.put(key, new int[1024 * 10000]);
key = null;
//System.gc();
}
}

如下所示,添加 -XX:+PrintGCDetails以打印出GC信息;如您所见,实际上,JVM尝试执行完整的GC运行,但是失败了;我仍然不知道原因。如果我取消注释 System.gc();行,结果是肯定的,这是很奇怪的:
add new element 1
add new element 2
add new element 3
add new element 4
add new element 5
[GC (Allocation Failure) --[PSYoungGen: 48344K->48344K(59904K)] 168344K->168352K(196608K), 0.0090913 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
[Full GC (Ergonomics) [PSYoungGen: 48344K->41377K(59904K)] [ParOldGen: 120008K->120002K(136704K)] 168352K->161380K(196608K), [Metaspace: 5382K->5382K(1056768K)], 0.0380767 secs] [Times: user=0.09 sys=0.03, real=0.04 secs]
[GC (Allocation Failure) --[PSYoungGen: 41377K->41377K(59904K)] 161380K->161380K(196608K), 0.0040596 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 41377K->41314K(59904K)] [ParOldGen: 120002K->120002K(136704K)] 161380K->161317K(196608K), [Metaspace: 5382K->5378K(1056768K)], 0.0118884 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at test.DeadLock.main(DeadLock.java:23)
Heap
PSYoungGen total 59904K, used 42866K [0x00000000fbd80000, 0x0000000100000000, 0x0000000100000000)
eden space 51712K, 82% used [0x00000000fbd80000,0x00000000fe75c870,0x00000000ff000000)
from space 8192K, 0% used [0x00000000ff800000,0x00000000ff800000,0x0000000100000000)
to space 8192K, 0% used [0x00000000ff000000,0x00000000ff000000,0x00000000ff800000)
ParOldGen total 136704K, used 120002K [0x00000000f3800000, 0x00000000fbd80000, 0x00000000fbd80000)
object space 136704K, 87% used [0x00000000f3800000,0x00000000fad30b90,0x00000000fbd80000)
Metaspace used 5409K, capacity 5590K, committed 5760K, reserved 1056768K
class space used 576K, capacity 626K, committed 640K, reserved 1048576K

最佳答案

JVM会自行调用GC,但在这种情况下,它太少了,太迟了。
在这种情况下,清除内存的不仅是GC。
映射值很容易达到,并且在对映射值进行某些操作时会被映射本身清除。

如果您打开GC事件(XX:+ PrintGC),则输出如下:

add new element 1
add new element 2
add new element 3
add new element 4
add new element 5
add new element 6
add new element 7
[GC (Allocation Failure) 2407753K->2400920K(2801664K), 0.0123285 secs]
[GC (Allocation Failure) 2400920K->2400856K(2801664K), 0.0090720 secs]
[Full GC (Allocation Failure) 2400856K->2400805K(2590720K), 0.0302800 secs]
[GC (Allocation Failure) 2400805K->2400805K(2801664K), 0.0069942 secs]
[Full GC (Allocation Failure) 2400805K->2400753K(2620928K), 0.0146932 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

直到最后一次尝试将值(value)放入映射中时,才会触发GC。

直到映射键出现在引用队列上,WeakHashMap才能清除陈旧的条目。
映射键只有在被垃圾回收后才会出现在引用队列上。
在 map 有机会自行清除之前,会触发为新 map 值分配内存的操作。
当内存分配失败并触发GC时,将收集映射键。但这太少了,太晚了-没有足够的内存被释放来分配新的映射值。
如果减少有效负载,则可能最终会获得足够的内存来分配新的映射值,并且过时的条目将被删除。

另一种解决方案是将值本身包装到WeakReference中。这将允许GC清除资源,而无需等待 map 自行完成。
这是输出:
add new element 1
add new element 2
add new element 3
add new element 4
add new element 5
add new element 6
add new element 7
[GC (Allocation Failure) 2407753K->2400920K(2801664K), 0.0133492 secs]
[GC (Allocation Failure) 2400920K->2400888K(2801664K), 0.0090964 secs]
[Full GC (Allocation Failure) 2400888K->806K(190976K), 0.1053405 secs]
add new element 8
add new element 9
add new element 10
add new element 11
add new element 12
add new element 13
[GC (Allocation Failure) 2402096K->2400902K(2801664K), 0.0108237 secs]
[GC (Allocation Failure) 2400902K->2400838K(2865664K), 0.0058837 secs]
[Full GC (Allocation Failure) 2400838K->1024K(255488K), 0.0863236 secs]
add new element 14
add new element 15
...
(and counting)

好多了。

关于java - 尽管使用了WeakHashMap,但仍发生OutOfMemoryException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60584806/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com