Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
System.gc()之后未释放Java弱引用_Java_Reference_Garbage Collection_System_Weak - Fatal编程技术网

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

System.gc()之后未释放Java弱引用,java,reference,garbage-collection,system,weak,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()

我有一个简单的片段:

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());
我的问题是: (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;
语法是糖。编译器最终编译的是以下代码,因为“自动装箱”是javac想象的虚构(JVM对此一无所知,完全是javac为您完成的):

Integer x = Integer.valueOf(2);
当然,如果你调用
newinteger
,你总是会得到一个新的对象,因为,这就是规范所说的。您也可以对此进行测试:

System.out.println(new Integer(5) == new Integer(5));
上面打印的是
false

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


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

这与
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);
当然,如果你调用
newinteger
,你总是会得到一个新的对象,因为,这就是规范所说的。您也可以对此进行测试:

System.out.println(new Integer(5) == new Integer(5));
上面打印的是
false

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


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

@krzysztofcichochiki请解释可能随时更改。这个答案中解释的所有行为都在Javadoc和Java语言规范中有很好的文档记录。@krzysztofcichochi你错了。虽然我同意依赖整数缓存感觉很奇怪,但这个答案是准确的。关于WeakReference,只要引用的对象可以从整数缓存强访问,它就不会被清除。依赖内部缓存并不好,这只是实现细节,可以随时更改。System.gc()不能保证真正运行gc,它只是善意地要求jvm这样做。同样,这只是一个实现细节,您不能如此精确地依赖它,就像JComponent.repaint()和Thread.yeld()一样,尽管这些调用通常会产生一些效果,您不能真正保证他们会在特定的时间内运行底层任务。您应该连接到gc通知:以确保在您检查这些通知时确实执行了gcvalues@KrzysztofCichocki请解释一下,任何时候都可能发生变化。这个答案中解释的所有行为都在Javadoc和Java语言规范中有很好的文档记录。@krzysztofcichochi你错了。虽然我同意依赖整数缓存感觉很奇怪,但这个答案是准确的。关于WeakReference,只要引用的对象可以从整数缓存强访问,它就不会被清除。依赖内部缓存并不好,这只是实现细节,可以随时更改。System.gc()不能保证真正运行gc,它只是善意地要求jvm这样做。同样,这只是一个实现细节,您不能如此精确地依赖它,就像JComponent.repaint()和Thread.yeld()一样,尽管这些调用通常会产生一些效果,您无法真正保证它们会在特定的时间内真正运行基础任务。您应该连接到gc通知:为了确保在检查这些值时确实执行了gc,您应该连接到gc通知:为了确保在检查这些值时确实执行了gc检查这些值您应该连接到gc通知:为了确保在检查这些值时确实执行了gc