Java弱引用在系统运行后未被释放。gc()
我有一个简单的片段:
Integer integer = 2;
WeakReference<Integer> wi = new WeakReference<>(integer);
WeakReference<Integer> sr = new WeakReference<>(new Integer(3));
System.out.println(wi.get());
System.out.println(sr.get());
System.gc();
System.out.println("step 1 wi = " + wi.get());
System.out.println("step 1 sr =: " + sr.get());
integer = null;
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("step 1 wi = " + wi.get());
System.out.println("step 1 sr =: " + sr.get());
“System.gc()”调用应该强制回收所有弱引用,对吧,我甚至等了一秒钟以确保gc()发生。 但即使设置了“integer=null”,wi也拒绝为null。而sr在“System.gc()”之后正好为null。它打印:
2
3
step 1 wi = 2
step 1 sr =: null
step 1 wi = 2
step 1 sr =: null
我的问题是: (1) wi和sr的核心区别是什么? (2)如何使jvm循环wi
非常感谢
# 1 楼答案
它与
System.gc()
不保证这一事实(它不保证,但这不是你看到你看到的东西的原因)或者弱引用如何与gc交互无关j.l.Integer类为
Integer
的所有字节值(从-128到+127)保存实例的“缓存”。你可以在行动中观看:上面打印了
true false
此代码:
是糖。编译器最终编译的是以下代码,因为“自动装箱”是javac想象的虚构(JVM对此一无所知,完全是javac为您这么做的):
当然,如果你调用
new Integer
,你总是会得到一个新的对象,因为,嗯,规范是这么说的。你也可以测试一下:上面打印了
false
实际上,
java.lang.Integer
类本身持有对wi
引用指向的对象的引用,因此,它永远不会被收集重试完全相同的代码,但这一次,请尝试“=128”,而不是“=2”,这一次它将收集与sr相同的代码