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个在数值内,有一个缺失.请设计一个算法将缺失 ...
随机推荐
- 判断语句的嵌套和switch判断
Scanner scanner = new Scanner(System.in);int i = scanner.nextInt();int i2 = scanner.nextInt();if (i& ...
- git和提交分支
实习到今天,已经开始做项目一段时间了,当然只是实习生的个人项目. 项目是导师发在git上面的,要求我们用git的PR提交 可是我不会啊...git仅仅是简单的个人提交总的项目到仓库里,什么新建分支,p ...
- 「SDOI2016」征途 题解
「SDOI2016」征途 先浅浅复制一个方差 显然dp,可以搞一个 \(dp[i][j]\)为前i段路程j天到达的最小方差 开始暴力转移 \(dp[i][j]=min(dp[k][j-1]+?)(j- ...
- Spring源码学习笔记9——构造器注入及其循环依赖
Spring源码学习笔记9--构造器注入及其循环依赖 一丶前言 前面我们分析了spring基于字段的和基于set方法注入的原理,但是没有分析第二常用的注入方式(构造器注入)(第一常用字段注入),并且在 ...
- 基于Vue.js2.6结合h5来实现视频播放画中画技术(Picture-in-Picture)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_125 在开发基于vue.js的在线视频教育平台的时候,我们会注意一个小问题,就是如果用户在观看播放视频的同时,也会往下拖动窗口浏览 ...
- GP查询表状态常用SQL
- 典型相关分析CCA计算过程
本文介绍了CCA解决的问题,CCA原理的推导过程,以及对计算结果物理意义的解释.并且通过SPSS和R操作演示了一个关于CCA的例子.数据文件下载参考[8],SPSS输出结果文件下载参考[9],R代 ...
- React报错之无法在未挂载的组件上执行React状态更新
正文从这开始~ 总览 为了解决"Warning: Can't perform a React state update on an unmounted component" ,可以 ...
- SkiaSharp 之 WPF 自绘 投篮小游戏(案例版)
此案例主要是针对光线投影法碰撞检测功能的示例,顺便做成了一个小游戏,很简单,但是,效果却很不错. 投篮小游戏 规则,点击投篮目标点,就会有一个球沿着相关抛物线,然后,判断是否进入篮子里,其实就是一个矩 ...
- 汇编语言基于8086CUP(想学操作系统的前奏!!!)
汇编语言基于8086CUP(想学操作系统的前奏!!!) 1.汇编语言的产生 1.1.思维图 1.2.单位转换 1B=8bit 1KB=1024B 1MB=1024KB 1GB=1024MB 1TB=1 ...