JDK 7文档对此有一个说法SoftReference
:
" 在虚拟机抛出OutOfMemoryError之前,保证可以清除对软可访问对象的所有软引用."
然而,在我的测试程序中,我看到的OutOfMemoryError
一致(除了"陌生人行为"一节):
// RefObjectTest.java import java.util.*; import java.lang.ref.*; public class RefObjectTest { public static void main(String[] args) { ArrayListleaks = new ArrayList<>(); byte[] obj = new byte[10 * 1024 * 1024]; SoftReference ref = new SoftReference<>(obj); // WeakReference is supposed to be eagerly GC'ed, but I see no // difference in terms of program behavior: still get OOME. // // WeakReference ref = new WeakReference<>(obj); obj = null; while(true) { byte[] x = ref.get(); if(x == null) { System.out.println("Referent stands garbage collected!!"); break; } else { System.out.println("Referent still alive."); } // Leak memory in small, 10k increments. If soft reference // worked the way it's advertized, then just before the OOME, the // 10MB referent should have been GC'ed to accomodate this small // 10K new memory request. But it doesn't appear to work that way! // try { leaks.add(new byte[10 * 1024]); // } catch(OutOfMemoryError e) { // System.out.println(ref.get() == null ? "Referent cleared" : // "Referent still alive"); // } // VERY STRANGE: If I re-instate the above try-catch block, then no OOME is // thrown, and the program keeps printing "Referent still alive" lines // forever until I finally kill it with a Ctrl+C. // Uncommenting gc() tends to delay the OOME in terms of time, // but OOME eventually does happen, and after the same number of // iterations of this loop. // // System.gc(); } } }
这是输出:
$ java -Xmx15m RefObjectTest Referent still alive. ... Referent still alive. Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at RefObjectTest.main(RefObjectTest.java:38)
陌生人的行为
什么是非常奇怪的是,如果我重新启动try-catch块,该程序似乎永远运行正常,打印"Referent仍然活着".直到我累了并杀了它.
$ java -version java version "1.7.0_45" Java(TM) SE Runtime Environment (build 1.7.0_45-b18) Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode) $ $ uname -a Linux ida 3.10.11-100.fc18.x86_64 #1 SMP Mon Sep 9 13:06:31 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
我在这一切中缺少什么?