内存管理器(二十一)标记-清扫回收算法

内存回收一共有四种基本的算法及若干高级算法:

标记-清扫,标记-复制,标记-整理,引用计数。

任何自动内存管理都需要面临三个基本任务:

1.为新对象分配空间。

2.确定存活时间。

3.回收死亡对象所占空间。

讨论前提:

多线程条件下,只有一个回收线程。

垃圾回收前提:

“万物静止式”回收,所有的资源分配器都会静止,回收线程开始运作,从资源分配器的角度来看回收过程是原子的。

回收方式:

通过“万物静止”获取“堆”的一个快照,然后回收资源。

标记-清扫算法:

这个算法分为两个阶段:

第一阶段:

追踪阶段:回收器从根集合开始遍历对象图,标记每一个遇到的对象。

第二阶段:

清扫阶段:回收器检查堆中的每一个对象,将所有未标记的对象作为垃圾回收。

这个算法是一种“间接”的回收方式。

在这里分配器和回收器普遍具的几个行为:

分配器:

@创建,分配资源方法。

@读,读取已经分配资源的方法。

@写,修改已经分配资源内容。

这个算法思想还是比较简单的:先来一个伪代码:
new: new_obj = alloc(); /*尝试分配*/ if(new_obj == NULL){ free_heap(); /*失败,回收资源再次尝试*/ } new_obj = alloc(); if(new_obj == NULL){ /*无内存,终止*/ error:out of memory; return new_obj; } return new_obj; atomic free_head(); mark_all(); /*标记所有*/ free(heapstart,heapend); /*释放内存*/ mark_all(): init_worklist(); /*初始化工作列表*/ for each flags in roots if (flags != NULL && not mark){ setmark(); add(worklist,flags); mark(); } mark(): /*递归式的标记*/ while worklist not empty flags = worklist.pop; for each fla in flags if(fla != NULL && not mark) setmark(); add(worklist,child); sweep(start,end): /*回收资源*/ for start to end if(start is marked){ unmarked(start); }else{ free(start); } start = start -> next; 

以上是最简单的标记-清扫算法接着我们它来看看三色抽象。三色抽象:Dijkstra 提出了三色抽象,真是个神人,哪哪都有他。三色抽象将对象划分为三种颜色,白色,灰色,黑色。颜色意义:白色:可能死亡对象,所有未被扫描的对象都是白色。灰色:初次扫描时的状态,此时他们为中间状态。黑色:处理完成的节点,(确定存活)为黑色。从根开始遍历进行标记,初步采用的是深度有先法。初次遍历的节点都会被染成灰色,进栈,然后出栈被标记查询有无子节点或者是否叶子节点做出相应的处理,全部处理完成的存活节点为黑色,而所有的节点最后只会变成白色或黑色。最后遍历结构释放所有非黑色的节点。对于此算法的优化

1.使用位图标记@标记过程只需读取存活对象的指针不会修改任何读对象@对于不包含引用的对象,同样不会读取别的东西位图的优势,许多证据表明,很多内存都是连续的簇,使用位图可以成块的回收资源,而遍历的方式极有可能产生页换出,高速缓存被刷新。这是不可饶恕的失误。2.使用懒惰清扫@不主动清扫,局部性原理,延时清理,很简单。3.优化高速缓存不命中的问题首先,我们清楚两个问题,高速缓存是按照FIFO原理活动的,而标记过程是按照LIFO过程遍历的,这就导致一个问题,高速缓存不命中。例如:高速缓存可以存储两个单位:高速存储单位              预读单位        下一个读取单位第一次      1   2                              无                      4第二次     2    4                            2  5                       5我们发现2其实是在缓存中的,并且我们预读了单位2 5 ,而将4 换出了高速缓存,如果不这样做,则2被换出,4 5进高速缓存,下一次回到2节点,再将2 换入,非常的不方便。标记-清扫算法小结在这个算法下:@不会引入额外的开销。@吞吐量非常高,最主要的消耗在于追踪指针。@整体位图优于局部位图。@安全性好,不需要使用移动操作。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值