Google I/O 2017上推出的新 GC 算法的原理

看了下youtube上的视频 youtube.com/watch?

貌似之前的Compact Copying Collector并不是concurrent的,然后在Android O里调整成为了Concurrent Copying Garbage Collector. 新的GC简单来说就是利用了read barrier来使得应用程序代码可以在GC过程中耗时最大的那些阶段依旧同GC一起运行。图是从Presentation里粘出来的,侵权删。

新的GC分为Pause, Copying, Reclaim三个阶段,以Region为单位进行GC。

Pause阶段:

<img data-rawwidth="1112" data-rawheight="556" src="https://pic4.zhimg.com/v2-c5f39f0ca3f2a0d213218f971e87981b_b.png" class="origin_image zh-lightbox-thumb" width="1112" data-original="https://pic4.zhimg.com/v2-c5f39f0ca3f2a0d213218f971e87981b_r.png">

这个阶段耗时非常少,这里很重要的一块儿工作是确定需要进行GC的region。当前进程中所有正被使用的那些region中存在高度碎片的region会被选中,而这些被选中的region被称为source region。在GC完成后这些被选中的source region就可以被释放了。从图中可以看出本次GC选中了中间的两个碎片比率很大的region作为source region。在Pause阶段完成对所有线程stack的walk并得到最终的root set之后,就可以唤醒所有的线程并进入到GC的下一个Copying阶段。

Copying阶段:

<img data-rawwidth="1110" data-rawheight="570" src="https://pic2.zhimg.com/v2-e190108ce592c25dc3a062907c5728ad_b.png" class="origin_image zh-lightbox-thumb" width="1110" data-original="https://pic2.zhimg.com/v2-e190108ce592c25dc3a062907c5728ad_r.png">

Copying阶段是整个GC中耗时最长的阶段。通过将source region中根据root set计算并标记为reachable的对象拷贝到destination region,并且确保在GC完成后没有任何指向source region中内存的引用,然后修改所有指向source region的活对象使他们指向新的destination region中的新地址。由于现在应用程序线程正在同GC线程一同运行,GC需要确保其它线程不会读到依旧指向source region的对象,而新的GC则使用了read barrier技术来达到这个目的。

<img data-rawwidth="1114" data-rawheight="564" src="https://pic3.zhimg.com/v2-742b6a5d48138f5661f838ff7603b97a_b.png" class="origin_image zh-lightbox-thumb" width="1114" data-original="https://pic3.zhimg.com/v2-742b6a5d48138f5661f838ff7603b97a_r.png">

所谓read barrier是一小段代码,并且被运行期环境(runtime)安插在field read前来防止其它线程看到指向source region的引用。如果其它线程在Copying阶段需要访问曾经存在于source region中的对象,GC的read barrier逻辑会负责截获这个读取并且将数据拷贝到destination region然后返回这个被拷贝到destination region的新引用。当所有的source region的所有reachable对象都被转移到destination region之后就可以进入到GC的下一个Reclaim阶段了

<img data-rawwidth="1102" data-rawheight="554" src="https://pic4.zhimg.com/v2-1bf2f9700cc0cea9c201d646ca9a1ee3_b.png" class="origin_image zh-lightbox-thumb" width="1102" data-original="https://pic4.zhimg.com/v2-1bf2f9700cc0cea9c201d646ca9a1ee3_r.png">

Reclaim阶段:在经过Copying阶段后,整个进程中就不再存在指向source regions的引用了,GC就可以将这些source region的内存释放供以后使用了。

新的GC算法在提高了GC效率的同时还得益于对后台任务甚至系统后台任务的支持,整个heap的平均尺寸得到了32%的下降。

<img data-rawwidth="992" data-rawheight="552" src="https://pic3.zhimg.com/v2-033fd4784aae7313d6e3fbc428b2f17e_b.png" class="origin_image zh-lightbox-thumb" width="992" data-original="https://pic3.zhimg.com/v2-033fd4784aae7313d6e3fbc428b2f17e_r.png">

而平均GC Latency也得到了大大的降低,具体对比见图

<img data-rawwidth="1102" data-rawheight="562" src="https://pic3.zhimg.com/v2-e8d728ed6bc65a240033cf3b4c2fdd0a_b.png" class="origin_image zh-lightbox-thumb" width="1102" data-original="https://pic3.zhimg.com/v2-e8d728ed6bc65a240033cf3b4c2fdd0a_r.png">

另外由于heap总是经过compact的,从而可以实现Thread Local Bump Pointer的简单内存分配器,因为现在分配内存不再需要复杂的free list管理只需要一个简单的pointer bump,内存分配的速度也得到了显著的提升。

<img data-rawwidth="1116" data-rawheight="544" src="https://pic3.zhimg.com/v2-d1501d9d10c4789cbc05c6cfbcba6ef6_b.png" class="origin_image zh-lightbox-thumb" width="1116" data-original="https://pic3.zhimg.com/v2-d1501d9d10c4789cbc05c6cfbcba6ef6_r.png">
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
视差图生成中的GC(Graph Cuts)算法主要是通过最小割来求解能量函数,从而得到视差图。在MATLAB中,可以使用Computer Vision Toolbox中的视差图算法来实现GC算法。 以下是MATLAB中视差图生成中的GC算法的一些步骤: 1. 读入左右图像,并进行预处理。 2. 使用stereoDisparity函数计算初始视差图。 3. 使用generateCostVolume函数将左右图像转化为代价体积。 4. 对代价体积进行平滑处理,以减少噪声。 5. 使用graphCut函数计算最小割,并得到视差图。 6. 对视差图进行后处理,以去除无效区域和平滑视差图。 下面是一个MATLAB示例代码,演示如何使用GC算法生成视差图: ```matlab % 读入左右图像 I1 = imread('left.png'); I2 = imread('right.png'); % 预处理图像 I1_gray = rgb2gray(I1); I2_gray = rgb2gray(I2); % 计算初始视差图 disparity_range = [0 64]; disparity_map = stereoDisparity(I1_gray, I2_gray, disparity_range); % 将左右图像转化为代价体积 cost_volume = generateCostVolume(I1_gray, I2_gray, disparity_range); % 平滑代价体积 smooth_cost_volume = smoothCostVolume(cost_volume); % 计算最小割,得到视差图 disparity_map = graphCut(smooth_cost_volume); % 后处理视差图 disparity_map = postProcess(disparity_map); % 显示结果 imshow(disparity_map, disparity_range); ``` 需要注意的是,这只是一个简单的示例代码,实际应用中还需要根据具体情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值