OutOfMemoryException尽管使用了WeakHashMap

问题描述 投票:1回答:2

如果不调用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 * 100000]);
        key = null;
        //System.gc();
    }
}

如下所示,添加-XX:+PrintGCDetails -Xloggc:F:/myapp-gc.log以打印出GC信息;如您所见,实际上,JVM尝试执行完整的GC运行,但是失败;我still不知道原因。如果我取消注释System.gc();行,结果是肯定的,这很奇怪:

Java HotSpot(TM) 64-Bit Server VM (25.212-b10) for windows-amd64 JRE (1.8.0_212-b10), built on Apr  1 2019 22:50:23 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 8344892k(4062288k free), swap 12801340k(4141124k free)
CommandLine flags: -XX:InitialHeapSize=133518272 -XX:MaxHeapSize=2136292352 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC 
1.635: [GC (System.gc()) [PSYoungGen: 7400K->1486K(38400K)] 407400K->401494K(526336K), 0.0051165 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
1.641: [Full GC (System.gc()) [PSYoungGen: 1486K->0K(38400K)] [ParOldGen: 400008K->401373K(487936K)] 401494K->401373K(526336K), [Metaspace: 5393K->5393K(1056768K)], 0.0123136 secs] [Times: user=0.06 sys=0.00, real=0.01 secs] 
2.870: [GC (System.gc()) [PSYoungGen: 665K->32K(38400K)] 802039K->801405K(926720K), 0.0026008 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2.872: [Full GC (System.gc()) [PSYoungGen: 32K->0K(38400K)] [ParOldGen: 801373K->401095K(888320K)] 801405K->401095K(926720K), [Metaspace: 5393K->5393K(1056768K)], 0.0818341 secs] [Times: user=0.31 sys=0.00, real=0.08 secs] 
4.003: [GC (System.gc()) [PSYoungGen: 1331K->32K(38400K)] 802426K->801127K(926720K), 0.0043253 secs] [Times: user=0.05 sys=0.01, real=0.00 secs] 
4.007: [Full GC (System.gc()) [PSYoungGen: 32K->0K(38400K)] [ParOldGen: 801095K->401093K(888320K)] 801127K->401093K(926720K), [Metaspace: 5393K->5393K(1056768K)], 0.0844307 secs] [Times: user=0.30 sys=0.00, real=0.09 secs] 
5.142: [GC (System.gc()) [PSYoungGen: 665K->32K(38400K)] 801759K->801125K(926720K), 0.0044553 secs] [Times: user=0.03 sys=0.00, real=0.01 secs] 
5.147: [Full GC (System.gc()) [PSYoungGen: 32K->0K(38400K)] [ParOldGen: 801093K->401093K(888320K)] 801125K->401093K(926720K), [Metaspace: 5393K->5393K(1056768K)], 0.0797424 secs] [Times: user=0.30 sys=0.00, real=0.08 secs] 
6.280: [GC (System.gc()) [PSYoungGen: 665K->32K(38400K)] 801759K->801125K(926720K), 0.0046556 secs] [Times: user=0.06 sys=0.00, real=0.01 secs] 
6.285: [Full GC (System.gc()) [PSYoungGen: 32K->0K(38400K)] [ParOldGen: 801093K->401093K(888320K)] 801125K->401093K(926720K), [Metaspace: 5393K->5393K(1056768K)], 0.0784319 secs] [Times: user=0.26 sys=0.00, real=0.08 secs] 
7.421: [GC (System.gc()) [PSYoungGen: 665K->32K(38400K)] 801759K->801125K(926720K), 0.0053890 secs] [Times: user=0.05 sys=0.02, real=0.00 secs] 
7.426: [Full GC (System.gc()) [PSYoungGen: 32K->0K(38400K)] [ParOldGen: 801093K->401093K(888320K)] 801125K->401093K(926720K), [Metaspace: 5393K->5393K(1056768K)], 0.0791797 secs] [Times: user=0.27 sys=0.00, real=0.08 secs] 
8.565: [GC (System.gc()) [PSYoungGen: 665K->32K(38400K)] 801759K->801125K(926720K), 0.0062035 secs] [Times: user=0.06 sys=0.00, real=0.01 secs] 
8.571: [Full GC (System.gc()) [PSYoungGen: 32K->0K(38400K)] [ParOldGen: 801093K->401093K(888320K)] 801125K->401093K(926720K), [Metaspace: 5393K->5393K(1056768K)], 0.0904973 secs] [Times: user=0.20 sys=0.00, real=0.09 secs] 
9.706: [GC (System.gc()) [PSYoungGen: 665K->32K(38400K)] 801759K->801125K(926720K), 0.0042666 secs] [Times: user=0.06 sys=0.00, real=0.00 secs] 
9.710: [Full GC (System.gc()) [PSYoungGen: 32K->0K(38400K)] [ParOldGen: 801093K->401093K(888320K)] 801125K->401093K(926720K), [Metaspace: 5393K->5393K(1056768K)], 0.0802856 secs] [Times: user=0.31 sys=0.00, real=0.08 secs] 
10.841: [GC (System.gc()) [PSYoungGen: 665K->32K(38400K)] 801759K->801125K(926720K), 0.0042232 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
10.846: [Full GC (System.gc()) [PSYoungGen: 32K->0K(38400K)] [ParOldGen: 801093K->401093K(888320K)] 801125K->401093K(926720K), [Metaspace: 5393K->5393K(1056768K)], 0.0787229 secs] [Times: user=0.31 sys=0.00, real=0.08 secs] 
11.995: [GC (System.gc()) [PSYoungGen: 665K->32K(38400K)] 801759K->801125K(926720K), 0.0058578 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
12.001: [Full GC (System.gc()) [PSYoungGen: 32K->0K(38400K)] [ParOldGen: 801093K->401093K(888320K)] 801125K->401093K(926720K), [Metaspace: 5394K->5394K(1056768K)], 0.0793483 secs] [Times: user=0.25 sys=0.00, real=0.08 secs]
java out-of-memory weak-references
2个回答
0
投票
如果打开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

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

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

另一个解决方案可能是将值本身包装到WeakReference中。这将允许GC清除资源,而无需等待地图自行完成。这是输出:

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)

好多了。


-1
投票
© www.soinside.com 2019 - 2024. All rights reserved.