GC算法-标记压缩算法
概述
还记得标记清除
和复制算法
的问题么? 堆使用效率低和碎片化问题. 那么有没有能够利用整个堆, 有没有内存碎片化问题的算法呢? 这就是标记压缩算法
了.
简单来说, 标记压缩算法就是将堆中的所有活动对象整体向左移, 将对象间的空隙消除.
在GC执行前的内存:
GC执行后的内存:
恩, 就是这么个意思.
实现
如何实现上面的操作呢? 首先, 要将所有活动对象标记出来. 这是标记阶段, 跳过了, 跟标记清除
一样操作就行. (这里每个对象都有一个mark
属性, true为活动对象)
标记完了, 那就剩下压缩操作了. 如何进行呢?
遍历堆, 将所有活动对象挪到左边. 但是, 后面有对象引用了前边的对象, 你就找不到新的指针了, 因为那块地址很可能已经被覆盖了.
....
最后想了想, 还是得老老实实地三步走:
遍历堆, 将所有对象通过计算得到新的地址并保存
遍历堆, 将所有子对象的地址更新为新的地址, 同时更新根集合中的指针.
遍历堆, 将对象集体迁移. 指针的问题都解决了, 可以将对象搬到新家了.
步骤一: 计算所有对象的新地址
// HEAP_START 是堆的开始位置, HEAP_END 是堆得结束位置
obj = HEAP_START
newAddr = HEAP_START
// 遍历所有活动对象
while(obj < HEAP_END){// 非活动对象, 跳过if(obj.mark != true){obj += obj.size;continue;}// 记录新的地址obj.newAddr = newAddrnewAddr += obj.size// 继续遍历obj += obj.size
}
这遍完后, 所有活动对象都保存了自己的新地址, 然后就可以将所有指针的地址进行更新了.
步骤二: 更新所有指针
// 更新根集合中的指针
for(obj in roots){obj = obj.newAddr
}
/*
更新所有活动对象的指针
当然, 这里也可以修改为遍历所有活动对象, 并将指针进行更新. 但是会出现各种重复处理、指针覆盖等问题, 就直接遍历堆了.
*/
obj = HEAP_START
while(obj < HEAP_END){if(obj.mark != true){obj += obj.size;continue;}// 更新子对象for(child in children){child = child.newAddr}obj += obj.size
}
至此, 所有指针都已经更新完毕, 但是, 对象还没有移动. 只剩下最后一步了, 将对象按照步骤一的规律, 向左排排坐就好啦.
步骤三: 迁移对象
obj = newAddr = HEAP_START
while(obj < HEAP_END){if(obj.mark != true) {obj += obj.size;continue;}// 将obj的数据复制到newAddr处copyData(newAddr, obj, obj.size);// 清空数据, 为下一次GC做准本newAddr.mark = false;newAddr.newAddr = null;// 遍历下一个对象obj += obj.sizenewAddr += obj.size
}
至此, 实现基本完成. 创建对象分配内存的操作与复制算法
一样. 这个算法简直是融合了标记清除
和复制算法
的优点, 解决了他们的问题, 不光堆的使用效率变高了, 而且也没有内存碎片的问题了. 但是, 就是, 只不过要对堆进行三次遍历而已. 不过没关系啦, 毕竟有失才有得嘛. 不过是时间换空间了.
而这, 也是标记压缩算法
最大的问题了, 执行时间太久了, 标记清除
对堆进行一次遍历, 而标记压缩
要进行三次. 三倍的时间. 可想而知.
不过也有伟人说了, 算法没有好不好, 只有是否适合. 这几种可达性
的算法各有优劣吧.
标记压缩的衍生
Two-Finger算法
将堆的遍历次数减少到两次.
如上图所示, 在第一次遍历的时候, 指针1从前向后寻找空闲地址, 指针2从后向前寻找活动对象, 找到后在原地址中记录新地址, 并将对象进行复制.
第二次遍历就可以将所有对象中的指针进行更新了.
你也发现了, 这个算法如果不想发生内存碎片化, 那就只能令每个对象的空间都是相同的. 而事实上也确实是这样. 强行规定每个对象都占用相同大小的空间, 我不知道这算法有什么应用场景. (原谅我的无知)
其他
还有一些其他的表格算法、lmmixGC算法等, 因为这两个我看的似懂非懂, 就不细说了.
标记压缩算法差不多就这么些. 告辞~~~
GC算法-标记压缩算法相关推荐
- 【Android 内存优化】垃圾回收算法 ( 内存优化总结 | 常见的内存泄漏场景 | GC 算法 | 标记清除算法 | 复制算法 | 标记压缩算法 )
文章目录 一. 内存优化总结 二. 常见的内存泄漏场景 三. 内存回收算法 四. 标记-清除算法 ( mark-sweep ) 五. 复制算法 六. 标记-压缩算法 一. 内存优化总结 内存泄漏原理 ...
- GC算法 (标记清除、复制、标记整理、 分代收集) 、 新生代 老年代
一.标记-清除算法(Mark-Sweep) 1标记阶段:首先通过根节点,标记所有从根节点开始的可达对象.未被标记的对象就是未被引用的垃圾对象 2清除阶段:清除所有未被标记的对象. 不足:1效率问题 ...
- GC算法-标记清除算法
概述 标记清除算法, 描述起来很简单, 从名字上就能看出, 分为两个阶段: 标记阶段: 遍历所有对象, 将活动对象都打上标记 清除阶段: 遍历堆, 将没有标记的对象释放掉. 介绍完毕, 本文结束. 开 ...
- 【超详细】JVM之内存管理和GC算法
一:JVM架构之class字节码 JVM整体架构(HotSpot JVM) java启动命令 java程序的允许需要使用java命令来负责启动 java启动的时候需要找到入口main方法 java启动 ...
- JVM(三)GC垃圾回收以及四种GC算法
JVM(三) 学习视频链接,以示尊重:https://www.bilibili.com/video/BV1iJ411d7jS?p=4 图片来源:https://blog.csdn.net/weixin ...
- JVM 知识梳理 (二) GC算法
文章目录 一.前言 二.判定哪些对象需要被GC 引用计数法Reference Count 可达性算法(引用链法Tracing) 三.GC算法 标记-清除 标记-压缩 复制算法 总结 分代收集 补充:H ...
- JVM入门(位置、体系结构、类加载器、双亲委派机制、沙箱安全机制、Native、PC寄存器、方法区、堆(新生区{伊甸园区、幸存区}、养老区、永久区)、OOM、GC算法、JMM)
目录 一.JVM的位置 二.JVM的体系结构 三.类加载器 1.类加载器举例 2. JVM中提供了三层的ClassLoader 3. 双亲委派机制(重要) 3.1 工作原理 3.2.优点 四.沙箱安全 ...
- 26 Java GC算法 垃圾收集器、标记 -清除算法、复制算法、标记-压缩算法、分代收集算法
26.Java GC算法 垃圾收集器 1.1.1标记 -清除算法 1.1.2复制算法 1.1.3标记-压缩算法 1.1.4分代收集算法 26.Java GC算法 垃圾收集器 概述 垃圾收集 Garba ...
- 垃圾回收机制之标记压缩算法与分代算法
标记清除算法其实和标记压缩算法其实非常相同,标记压缩算法是在标记清除算法之上,解决内存碎片化的问题,就是删不干净的问题,因为他的整个排序不是很好,标记压缩,有的地方叫做标记整理,都是一个意思,标记压缩 ...
最新文章
- Python基础01-Python环境搭建与HelloWorld
- Qt 之 Qt/Qt Lite 自编译详解(VS/MinGW/...)
- 04/28/2010 类,对象,变量
- python脚本自动化盲注_三、基于报错型注入和sql盲注的自动化实现
- VS2019调试查看变量_单片机编程软件一点通,IAR单片机编程软件工程调试方法
- 用FileZilla搭建的Ftp其他电脑无法访问的问题
- 数据结构-约瑟夫问题课后作业
- linux SO文件
- 远在美国的凤姐为何选择回国理財?
- Oracle 根据业务创建新的用户
- 那些年使用Android studio遇到的问题
- 服务器每个月维护要1000元,5月24日服务器例行维护公告(已完成)
- SpringBoot-短信发送
- spanning tree protocol
- c语言过磅系统,衡安无人值守地磅称重系统过磅流程
- 使用Python进行12306抢票
- RFC868--时间协议客户机与服务器的实现
- 计算机表格中平方根符在哪插入,开方符号-平方根符号怎么打?平方根符号在word和Excel中怎么打?上面 爱问知识人...
- R语言的修仙之道--R语言之后天境界
- matlab绘制垂线(x轴或y轴)
热门文章
- Modbus协议栈应用实例之三:Modbus TCP客户端应用
- 计算机PPT03,南京大学计算机网络课件03.ppt
- 如何计算实际物理地址?
- 如何做推荐系统 java_Java程序员的日常——SpringMVC+Mybatis开发流程、推荐系统
- 一元三次方程重根判别式_如何求一元三次方程
- python删除txt指定内容_python删除文件中指定内容
- python 3.7.732位安装步骤_Python3.7安装pyaudio教程解析
- mysql操作json优点和缺点_SQL-mysql操作json
- db2 sql 判断select是否为空_学会复杂一点的SQL语句:Oracle DDL和DML
- qt执行命令行失败_QT缺少 qtcore4.dll,debug下运行不成功