System.gc()之后无法释放Java弱引用

时间:2019-01-26 15:15:17

标签: java reference garbage-collection system weak

我有一个简单的代码段:

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()发生。 但是,即使设置了“整数= 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回收无线?

非常感谢。

1 个答案:

答案 0 :(得分:2)

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;

是语法糖。编译器最终最终编译的内容是以下代码,因为“自动装箱”是javac想象力的虚构(JVM对此一无所知,完全是javac为您完成的工作),是以下代码:

Integer x = Integer.valueOf(2);

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

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

以上打印false

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

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