GC plan_phase二叉树挂接的一个算法
楔子
在看GC垃圾回收plan_phase的时候,发现了一段特殊的代码,仔细研究下得知,获取当前数字bit位里面为1的个数。
通过这个bit位为1的个数(count),来确定挂接当前二叉树子节点的一个地方。
算法
size_t logcount (size_t word)
{
//counts the number of high bits in a 16 bit word.
assert (word < 0x10000);
size_t count;
count = (word & 0x5555) + ( (word >> 1 ) & 0x5555);
count = (count & 0x3333) + ( (count >> 2) & 0x3333);
count = (count & 0x0F0F) + ( (count >> 4) & 0x0F0F);
count = (count & 0x00FF) + ( (count >> 8) & 0x00FF);
return count;
}
counts the number of high bits in a 16 bit word.这一段英文注释很有误导性,它的意思翻一下大致是:获取当前16位字里面的高位bit数。
如果按照这个理解,基本上不知道这个logcount函数是干嘛的。
但实际上它做的事情非常简单。
举个例子:
5的二进制:0101,那么经过logcount函数计算之后,返回值为2。因为5的二进制里面有两个1。
以此类推,6返回2,7返回3,8返回1。
背景
GC垃圾回收的计划阶段,当plan_phase构建二叉树的时候,需要区分根节点,左子节点,和右子节点。新加入的新节点作为根节点,新节点的左子节点(G)就是上一个根节点(C)的右子节点。新节点本身又作为上一个根节点(C)的右子节点。
图:

上面这个算法的作用就是,把新加入的新节点挂接到二叉树深度N(logcount返回值)的地方。
图两个二叉树,分别深度为2和3。logcount返回其参数bit位里面为1的个数,作为二叉树的深度。然后进行一个挂接。其行为逻辑是二叉树构建的核心。
整体
GC计划阶段(plan_phase)的二叉树构建主要是为后面的重定位,压缩和清扫做准备。
二叉树是其关键一步。
大致为:
1.区分固定对象和非固定对象,如果非固定对象后面跟着非固定对象就会形成一个堆段,如果后面继续有非固定对象,则继续加入这个小堆段。如果后面跟着固定对象则到小堆段到此为止。然后判断固定对象后面是否跟着固定对象,如果是则把这两个固定对象形成一个小堆段。后面继续判断,如果还是固定对象则加入到小堆段。如没有,则此小堆段到此为止。其逻辑跟非固定对象一样。如此一直遍历完这个堆,这样的话堆里面形成了一个个小堆段。
2.这些小堆段,会被plan_phase当成一个个的节点,然后把这些节点通过相关的逻辑构建成一颗二叉树。
3.如果二叉树过于庞大,则无论是在时间还是在空间上的复杂度都很高。为了避免性能问题,于是引入了brick_table来分割这颗庞大的二叉树
结尾
理解其行为,则需联系上下文,查看其整体构建,然后逐步推导。

GC plan_phase二叉树挂接的一个算法的更多相关文章
- .Net CLR GC plan_phase二叉树和Brick_table
楔子 别那么懒,勤快点.以下取自CLR PreView 7.0. 主题 GC计划阶段(plan_phase)主要就两个部分,一个是堆里面的对象构建一颗二叉树(这颗二叉树的每个节点包含了诸如对象移动信息 ...
- 对于一棵二叉树,请设计一个算法,创建含有某一深度上所有结点的链表。 给定二叉树的根结点指针TreeNode* root,以及链表上结点的深度,请返回一个链表ListNode,代表该深度上所有结点的值,请按树上从左往右的顺序链接,保证深度不超过树的高度,树上结点的值为非负整数且不超过100000。
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x ...
- GC 为什么要挂起用户线程? 什么愁什么怨?
GC 为什么要挂起用户线程? 什么愁什么怨? 前言 JVM 系列文章的第一篇.敬请期待后续. 故障描述 某年某月某日 上午,线上发生故障,经过排查,发现某核心服务 Dubbo 接口超时. 故障根源 查 ...
- 介绍对称加密的另一个算法——PBE
除了DES,我们还知道有DESede(TripleDES,就是3DES).AES.Blowfish.RC2.RC4(ARCFOUR)等多种对称加密方式,其实现方式大同小异,这里介绍对称加密的另一个算法 ...
- [每天默写一个算法]KMP
[每天默写一个算法]KMP 作业要求:默写String的KMP算法. KMP是经典的字符串匹配算法.复杂度为O(n+m) public static class StringKMP { /// < ...
- 推荐一个算法编程学习中文社区-51NOD【算法分级,支持多语言,可在线编译】
最近偶尔发现一个算法编程学习的论坛,刚开始有点好奇,也只是注册了一下.最近有时间好好研究了一下,的确非常赞,所以推荐给大家.功能和介绍看下面介绍吧.首页的标题很给劲,很纯粹的Coding社区....虽 ...
- cc150:实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针
实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针. 样例: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不须要返回什么,得到一个新链表:a- ...
- 设单链表中存放n个字符,试设计一个算法,使用栈推断该字符串是否中心对称
转载请注明出处:http://blog.csdn.net/u012860063 问题:设单链表中存放n个字符.试设计一个算法,使用栈推断该字符串是否中心对称,如xyzzyx即为中心对称字符串. 代码例 ...
- python学习:设计一个算法将缺失的数字找出来。
算法题 已知整型数值 a[99], 包含的所有99个元素都是从1-100中随机取值,并且这99个数两两互不相等,也就是说从1到100这100个数字有99个在数值内,有一个缺失.请设计一个算法将缺失 ...
随机推荐
- 从零开始Blazor Server(1)--项目搭建
项目介绍 本次项目准备搭建一个使用Furion框架,Blazor的UI使用BootstrapBlazor.数据库ORM使用Freesql的后台管理系统. 目前的规划是实现简单的注册,登录.增加管理员跟 ...
- TensorFlow自定义训练函数
本文记录了在TensorFlow框架中自定义训练函数的模板并简述了使用自定义训练函数的优势与劣势. 首先需要说明的是,本文中所记录的训练函数模板参考自https://stackoverflow.com ...
- python第三方模块与内置模块
目录 openpyxl模块 random随机模块 hashlib加密模块 subprocess模块 logging模块 openpyxl模块 1.读取:openpyxl不擅长读数据 所以有一些模块优化 ...
- 关于javascript中this
------------恢复内容开始------------ 1 var number = 5; 2 var obj = { 3 number: 3, 4 fn1: (function () { 5 ...
- 多云部署多主模式的MGR集群,每个云一个MGR 节点,满足业务单元化改造的需求
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 本 ...
- Luogu3694 邦邦的大合唱站队 (状压DP)
状态由\(从前往后排好的长度\)和\(排好的团队\)决定,\(DP\)方程挺有思考价值的. #include <iostream> #include <cstdio> #inc ...
- Go 语言图片处理简明教程
虽然 Go 语言主要用于 Web 后端以及各类中间件和基础设施开发,也难免遇到一些图像处理的需求.Go 语言提供的 image 标准库提供了基本的图片加载.裁剪.绘制等能力,可以帮助我们实现一些绘图需 ...
- 基于 Apache Hudi 和DBT 构建开放的Lakehouse
本博客的重点展示如何利用增量数据处理和执行字段级更新来构建一个开放式 Lakehouse. 我们很高兴地宣布,用户现在可以使用 Apache Hudi + dbt 来构建开放Lakehouse. 在深 ...
- 青源Talk第8期|苗旺:因果推断,观察性研究和2021年诺贝尔经济学奖
biobank 英国的基金数据因果推断和不同的研究互相论证,而非一个研究得到的接了就行.数据融合,data fusion,同一个因果问题不同数据不同结论,以及历史上的数据,来共同得到更稳健.更高效的推 ...
- 【java】学习路径38-数学模型分析:不同方式复制文件所需的时间
测试文件:一段72kb的文本.约5.6MB大小的pdf论文.约38.9MB大小的无损音频文件. demo001 论<到灯塔去>的凝视主题.pdf irreplaceable.movpkg ...