楔子

在看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二叉树挂接的一个算法的更多相关文章

  1. .Net CLR GC plan_phase二叉树和Brick_table

    楔子 别那么懒,勤快点.以下取自CLR PreView 7.0. 主题 GC计划阶段(plan_phase)主要就两个部分,一个是堆里面的对象构建一颗二叉树(这颗二叉树的每个节点包含了诸如对象移动信息 ...

  2. 对于一棵二叉树,请设计一个算法,创建含有某一深度上所有结点的链表。 给定二叉树的根结点指针TreeNode* root,以及链表上结点的深度,请返回一个链表ListNode,代表该深度上所有结点的值,请按树上从左往右的顺序链接,保证深度不超过树的高度,树上结点的值为非负整数且不超过100000。

    /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x ...

  3. GC 为什么要挂起用户线程? 什么愁什么怨?

    GC 为什么要挂起用户线程? 什么愁什么怨? 前言 JVM 系列文章的第一篇.敬请期待后续. 故障描述 某年某月某日 上午,线上发生故障,经过排查,发现某核心服务 Dubbo 接口超时. 故障根源 查 ...

  4. 介绍对称加密的另一个算法——PBE

    除了DES,我们还知道有DESede(TripleDES,就是3DES).AES.Blowfish.RC2.RC4(ARCFOUR)等多种对称加密方式,其实现方式大同小异,这里介绍对称加密的另一个算法 ...

  5. [每天默写一个算法]KMP

    [每天默写一个算法]KMP 作业要求:默写String的KMP算法. KMP是经典的字符串匹配算法.复杂度为O(n+m) public static class StringKMP { /// < ...

  6. 推荐一个算法编程学习中文社区-51NOD【算法分级,支持多语言,可在线编译】

    最近偶尔发现一个算法编程学习的论坛,刚开始有点好奇,也只是注册了一下.最近有时间好好研究了一下,的确非常赞,所以推荐给大家.功能和介绍看下面介绍吧.首页的标题很给劲,很纯粹的Coding社区....虽 ...

  7. cc150:实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针

    实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针. 样例: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不须要返回什么,得到一个新链表:a- ...

  8. 设单链表中存放n个字符,试设计一个算法,使用栈推断该字符串是否中心对称

    转载请注明出处:http://blog.csdn.net/u012860063 问题:设单链表中存放n个字符.试设计一个算法,使用栈推断该字符串是否中心对称,如xyzzyx即为中心对称字符串. 代码例 ...

  9. python学习:设计一个算法将缺失的数字找出来。

    算法题   已知整型数值 a[99], 包含的所有99个元素都是从1-100中随机取值,并且这99个数两两互不相等,也就是说从1到100这100个数字有99个在数值内,有一个缺失.请设计一个算法将缺失 ...

随机推荐

  1. python 异常捕捉与异常处理

    简介 在实际开发中,为了防止异常界面直接被用户看到,往往我们会采用捕捉异常的方式来进一步处理异常. 异常捕捉 如下代码由于下标越界会导致异常 data = range(10) print(data[1 ...

  2. vue项目导航菜单实现

    vue项目导航菜单问题 目标:横向菜单点击跳转,颜色变换,刷新可保持状态 // 模板template中通过循环菜单列表生成,动态类名改变颜色 <li v-for="(item, ind ...

  3. Python logging日志管理

    import logging logger = logging.getLogger("simple_example") logger.setLevel(logging.DEBUG) ...

  4. Jenkins使用pipeline部署服务到远程服务器

    写这篇文章是对之前搭建Jenkins做的修改和完善,让jenkins更好的为我们服务 Docker搭建Jenkins服务 使用过程中遇到的问题: 为方便部署,打算将jenkins用到的jdk11.ma ...

  5. Ubuntu 20.04安装Docker

    Docker学习系列文章 入门必备:十本你不容错过的Docker入门到精通书籍推荐 day1.全面的Docker快速入门教程 day2.CentOS 8.4安装Docker day3.Windows1 ...

  6. zabbix 报表动作日志 报错”503“

  7. 微软Azure配置中心 App Configuration (二):Feature Flag 功能开关特性

    写在前面 Web服务开发过程中我们经常有这样的需求: 某些功能我必须我修改了配置才启用,比如新用户注册送券等: 某个功能需到特定的时间才启用,过后就失效,比如春节活动等: 某些功能,我想先对10%的用 ...

  8. 新年趣事之红包--"四边形"不等式优化DP

    目录 题目描述 输入 输出 思路 新年趣事之红包 时间限制: 1 Sec  内存限制: 64 MB 题目描述 xiaomengxian一进门,发现外公.外婆.叔叔.阿姨--都坐在客厅里等着他呢.经过仔 ...

  9. JZOJ 5796 划分 (容斥,数论,扩展CRT)

    题面 有一个未知的序列 x,长度为 n.它的 K-划分序列 y 指的是每连续 K 个数的和得到划 分序列,y[1]=x[1]+x[2]+....+x[K],y[2]=x[K+1]+x[K+2]+... ...

  10. django_day10_项目相关

    django_day10_项目相关 展示数据的方法 数据对象obj 普通字段 obj.字段名 ====> 数据库该字段的值 带choices参数的 obj.字段名 ====> 数据库该字段 ...