1

我对弱引用的理解:直到对象的所有强引用都丢失/删除之前,gc 无法将对象标记为删除。这意味着如果在某个时候,一个对象只被弱引用引用,那么该对象就有资格进行垃圾收集,并且下次 GC 运行时,它将标记该对象以删除。

1.我的理解正确吗?

为了验证我的理解,我创建了以下包含两个类的程序。

public class Customer {
    private String name;
    private String ssnId;
    private String phone;

    public Customer(String name, String ssnId, String phone) {
        this.name = name;
        this.phone = phone;
        this.ssnId = ssnId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSsnId() {
        return ssnId;
    }
    public void setSsnId(String ssnId) {
        this.ssnId = ssnId;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String toString()
    {
        return ssnId + name + phone; 
    }

}

public class TestClass {

    public static void main(String[] args) {
        Customer cust = new Customer("ABCD", "001 ", "Phone Number");
        WeakReference<Customer> weakcust = new WeakReference<Customer>(cust);
        int i = 0;
        while(true)
        {
            if(weakcust.get() != null)
            {
                i++;
                System.out.println(i + " " + weakcust.get());
            }
            else
            {
                System.err.println("Object's deleted");
                break;
            }
        }
    }
}

从逻辑上讲,这段代码应该继续打印客户的信息。

令我惊讶的是,我发现即使我没有将 cust 引用设置为 null,GC 也会删除 cust 指出的对象。一段时间后,程序会打印“Object's Deleted”</p>

2.为什么会这样?

我相信这可能是因为编译器正在优化代码,并且由于代码中不再使用 cust 引用,编译器自行将其设置为 null。如果我错了,请纠正我。

4

2 回答 2

0

问题是您的强引用对象客户本身没有被任何人引用,除了弱引用(这是一个弱引用)。所以它被标记为垃圾收集。一旦客户被垃圾收集,你就会看到你看到的行为。
在现实世界的应用程序中,您的客户会在某处被引用,并且只有当它被取消引用时,才会被垃圾回收。

于 2013-02-13T21:04:38.380 回答
0

cust将变量分配给weakcust 后,您没有访问该变量。JVM 优化注意到您似乎不再需要它,因此它决定在之后丢弃它。

将其转换为静态变量class Main可能会改变这种行为。

于 2013-02-13T21:08:49.243 回答