1 java garbage-collection reference weak-references
我是 Java 的新手。我现在正在学习 WeakReference 的概念。我遇到了一个可能看起来很愚蠢的问题,但我只是想找出原因。问题是:根据 Java 文档,“弱引用对象,它不会阻止其所指对象被终结、终结和回收。”
所以我做了这个小测试:
import java.lang.ref.WeakReference;
public class A {
public static void main(String[] args) {
A a = new A();
WeakReference<A> wr = new WeakReference<>(a);
a = null;
A a1 = wr.get();
System.out.println(a);
System.out.println(a1);
try {
System.gc();
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(a1);
}
@Override
protected void finalize( ) {
System.out.println(Thread.currentThread().getName() + ": See ya, nerds!");
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我注意到在 GC 运行后,wr.get()仍然可以返回我期望为 null 的对象,并且finalize()没有调用该方法。那么出了什么问题呢?提前感谢您的帮助!:)
你的测试前提是有缺陷的。System.gc()只是运行垃圾收集器的提示。它经常被忽略。
从文档:
调用 gc 方法表明Java 虚拟机花费精力来回收未使用的对象,以使它们当前占用的内存可用于快速重用。当控制从方法调用返回时,Java 虚拟机已尽最大努力从所有丢弃的对象中回收空间。
(强调我的)
将来,您可以使用 VM 选项-verbose:gc并-XX:+PrintGCDetails查看垃圾收集器在做什么。
更重要的是,您还可以非常快速地从弱引用中取出引用并将其放回强引用中:
A a = new A();
WeakReference<A> wr = new WeakReference<>(a);
a = null; // no strong references remain
A a1 = wr.get(); // the instance now has a strong reference again
Run Code Online (Sandbox Code Playgroud)
除非在这两个指令之间发生垃圾回收,否则对象将不会被垃圾回收。
如果您删除a1,则您的代码在我运行时的行为与您预期的一样(不过,由于我回答的第一部分,您的里程可能会有所不同):
class A
{
public static void main(String[] args)
{
A a = new A();
WeakReference<A> wr = new WeakReference<>(a);
a = null;
System.out.println(a);
try {
System.gc(); // instance of A is garbage collected
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(wr.get());
}
@Override
protected void finalize( )
{
System.out.println(Thread.currentThread().getName() + ": See ya, nerds!");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
806 次 |
| 最近记录: |