引用计数
最后更新于:2022-04-02 04:09:15
[TOC]
## 引用计数

- 每次引用一次 Person,就会在ref上加1(Stack上new Person(),HEAP的Array上引用了一次)
### 基于扫描的实现
- 维护一张引用表
- 每次扫描删除引用计数为0的节点

全部删除需要扫描两次
第一次删除引用为0的,并减少引用次数,
第二次删除调整后引用为0的
### 基于图的实现(常用)

- "0"指向"1",标识"1"被"0"引用
- 圆圈外的为定点,圆圈中的为被引用次数
- 边有方向,就是有向图;边没有方向,就是无向图。
- 纵向表示被谁引用
- 横向表示引用了谁
In-degree 和 out-degree
- 纵向标识 In-degree,横向标识 out-degree
- 图中顶点1的 in-degree=2,也就是有两条边进入顶点1
- 图中顶点1的out- degree=0,也就是有0条边从顶项点1出去
- **In-degree=0代表可以马上回收**
用广度优先(BFS算法)进行图的表里
```
queue.enqueue(start)
visited ={start}
while(queue size>0){
v= queue.dequeue
visited.add(v)
for u in outNodes(item){
if(!visited contains(u)){
queue enqueue(u)
}
}
}
```
如 "start" 从"0" 开始,因为"0"的引用计数为0 ,把零列出回收清单中,并且查看到0引用了"1","2",把引用计数减1,如果减去1后引用计数为0,则标识也可以进行回收,
#### 一种解决环装引用的方案
- 增加一个检测环的程序(BFS)
- 发现环,手动删除一条边
- 再次从引用计数为0的节点开始BFS回收内存

## 问题
- 基于扫描的引用计数策略性能太慢→基于图的策略
- 每个对象需要多维护一个引用(ref) → 开销问题
- 如果Gc程序是另外的线程ref的维护会产生竞争条件,处理GC的时候
需要Stop- The-World
';