垃圾回收 Garbage Collect

本文探讨了垃圾收集(GC)过程中的可达性分析,通过标记-清除算法展示了对象的可达性变化。从根节点开始,当对象失去所有引用时变得不可达,从而可能被GC回收。文中通过示例解释了如何避免循环引用导致的问题,并提到了常见的引用计数和marksweep等垃圾回收策略。
摘要由CSDN通过智能技术生成

GC

class A
{
    public B b;
}

class B
{
    public A a;
}

void main()
{
    A a = new A();
    a.b = new B();
    B b = new B();
    b.a = new A();
    A a2 = new A();
    B b2 = new B();
   
    // 标记A
    a.b = null;
    // 标记B
    b.a.b = null;
    // 标记C
    b.a = null;
    // 标记D
    a2 = null;
    // 标记E
}

程序运行后,在标记A处,所有对象都是可达的(reachable)

graph
root(root)-->a
a((a))-->a.b
a.b((a.b))
root(root)-->b
b((b))-->b.a
b.a((b.a))-->b
root(root)-->a2
a2((a2))
root(root)-->b2
b2((b2))

在标记B处,a.b变为不可达(unreachable)

graph
root(root)-->a
a((a))-.->a.b
a.b((a.b))
root(root)-->b
b((b))-->b.a
b.a((b.a))-->b
root(root)-->a2
a2((a2))
root(root)-->b2
b2((b2))
style a.b fill:000,stroke:#f66,stroke-width:4px,stroke-dasharray: 5, 5

在标记C处,b.a.b指向null,但b.a仍可达

graph
root(root)-->a
a((a))-.->a.b
a.b((a.b))
root(root)-->b
b((b))-->b.a
b.a((b.a))-.->b
root(root)-->a2
a2((a2))
root(root)-->b2
b2((b2))
style a.b fill:000,stroke:#f66,stroke-width:4px,stroke-dasharray: 5, 5

在标记D处,b.a指向null,此时b.a不可达

graph
root(root)-->a
a((a))-.->a.b
a.b((a.b))
root(root)-->b
b((b))-.->b.a
b.a((b.a))-.->b
root(root)-->a2
a2((a2))
root(root)-->b2
b2((b2))
style a.b fill:000,stroke:#f66,stroke-width:4px,stroke-dasharray: 5, 5
style b.a fill:000,stroke:#f66,stroke-width:4px,stroke-dasharray: 5, 5

在标记E处,a2指向null,此时a2不可达

graph
root(root)-->a
a((a))-.->a.b
a.b((a.b))
root(root)-->b
b((b))-.->b.a
b.a((b.a))-.->b
root(root)-.->a2
a2((a2))
root(root)-->b2
b2((b2))
style a.b fill:000,stroke:#f66,stroke-width:4px,stroke-dasharray: 5, 5
style b.a fill:000,stroke:#f66,stroke-width:4px,stroke-dasharray: 5, 5
style a2 fill:000,stroke:#f66,stroke-width:4px,stroke-dasharray: 5, 5

若此时进行GC,则a.b,b.a,a2这三个对象都会被回收

mark sweep

常见的有引用计数(reference counting)和mark sweep

mark

从应用程序的root开始,遍历托管堆上的所有对象,将其标记为非活动的(需要被删除)

从这些对象的字段引用继续遍历,直到所有对象都被检查完毕。

如何避免标记时因为循环引用而造成死循环:如果一个对象已经被标记,则不再检查其字段

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值