在System.gc()之后不会释放Java弱引用



我有一个简单的片段:

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()"调用应该强制回收所有弱引用,对吧,我甚至等了1秒才确保gc()发生。但是,即使设置了"integer=null","wi"也拒绝为null。而sr在"System.gc()"之后为空。它打印:

2
3
step 1 wi = 2
step 1 sr =: null
step 1 wi = 2
step 1 sr =: null

我的问题:(1) wi和sr的核心区别是什么?(2)如何让jvm回收wi?

非常感谢。

这与System.gc()不能保证这一事实无关(它没有保证,但这不是您看到所看到的内容的原因),也与弱引用如何与gc交互无关。

j.l.Integer类为Integer保存了一个实例的"缓存",用于所有字节值,从-128到+127。你可以观看这个动作:

System.out.println(Integer.valueOf(127) == Integer.valueOf(127));
System.out.println(Integer.valueOf(128) == Integer.valueOf(128));

上面打印的是true false

此代码:

Integer x = 2;

是语法糖。编译器最终实际编译的是以下代码:

Integer x = Integer.valueOf(2);

当然,如果你调用new Integer,你总是会得到一个新对象,因为规范就是这么说的。你也可以测试一下:

System.out.println(new Integer(5) == new Integer(5));

上述打印CCD_ 5。

实际上,java.lang.Integer类本身拥有对wi引用所指向的对象的引用,因此,它永远不会被收集。

重试完全相同的代码,但这次不是'=2',而是尝试'=128',这次它将收集与sr相同的代码。

相关内容

  • 没有找到相关文章

最新更新