为什么在下面的程序中调用System.exit(0)?仅当映射引用变量为空时才应调用它。
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
public class ReferencesTest {
private WeakReference<Map<Integer, String>> myMap;
public static void main(String[] args) {
new ReferencesTest().doFunction();
}
private void doFunction() {
Map<Integer, String> map = new HashMap<Integer, String>();
myMap = new WeakReference<Map<Integer, String>>(map);
int i = 0;
while (true) {
if (myMap != null && myMap.get() != null) {
myMap.get().put(i++, "test" + i);
System.out.println("im still working!!!!"+i+" Map Size"+myMap.get().size());
System.gc();
} else {
System.out
.println("*******im free*******");
System.exit(0);
}
}
}
}
最后几行输出
im still working!!!!15586 Map Size15586
im still working!!!!15587 Map Size15587
im still working!!!!15588 Map Size15588
*******im free*******
答案 0 :(得分:6)
在map
周期内(或进一步向下),任何地方都不使用(未引用)VARIABLE while
。仅仅因为变量仍在范围内,如源中所示;或者它在方法的字节码中确实有一个指定的局部变量条目并不意味着THE VARIABLE map
实际上在RURTIME的范围内,特别是在JIT编译之后。
除非您使用选项进行编译以显式保留未使用的局部变量(在整个范围内),否则这是预期的行为。
证明(--XX:+PrintCompilation
):
im still working!!!!15586 Map Size15586
im still working!!!!15587 Map Size15587
im still working!!!!15588 Map Size15588
259509 23 % eu.revengineer.sync.ReferencesTest::doFunction @ -2 (144 bytes) made not entrant
*******im free*******
答案 1 :(得分:0)
我想你真正想要使用的是WeakHashMap(http://docs.oracle.com/javase/6/docs/api/java/util/WeakHashMap.html)。
对HashMap的弱引用将在内存压力下被删除,从而导致整个地图无法访问,甚至在您的情况下终止该程序。 WeakHashMap使用对其键的弱引用,因此只有映射在内存压力下会丢失(键,值)对。