博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
垃圾回收机制
阅读量:6761 次
发布时间:2019-06-26

本文共 1427 字,大约阅读时间需要 4 分钟。

1、 引用计数

    引用计数算法是垃圾回收最早的算法,有其优势,也有其劣势,但是现在已经很少有使用了。

原理:为每个对象添加一个计数器,表示对象的引用次数,每当创建一个新的引用指向该对象时其计数器就加1,每当指向该对象的引用失效时计数器就减1。当计数器的值为0时就会被浏览器回收。

优点:

可即刻回收垃圾:当计数器值为0时,会马上回收对象,提高内存使用效率STW(Stop-The-World)短: 回收垃圾时,浏览器会停止响应其他操作,引用计数不需要遍历堆,有效减少STW时间

缺点:

计数器的增减操作频繁计数器需要占用一定的内存实现繁琐,更新引用时很容易导致内存泄露。循环引用无法回收(最重要的缺点)

2、 标记清除

    现代浏览器使用最多的一种垃圾回收机制。

原理:从名字就可以看出,该算法分为两个步骤:1.标记所有可访问的对象;2.清除所有未被标记的对象。

优点:

算法实现简单。

缺点:

碎片化:清楚后的空间是不连续的,不利于后面空间的分配。分配速度慢:由于空间碎片化,所以每次分配需要遍历空闲链表。STW(Stop-The-World)长:两个阶段均要遍历整个堆。

优化:采用标记整理算法或标记压缩算法进行内存整理,避免内存碎片化。

3、 GC优化策略 - 分代回收

    V8 实现了准确式 GC,采用了分代式垃圾回收机制,将内存(堆)按照8:2分为老生代和新生代两部分,其中新生代又按照1:1分为了两块Survivor空间。

    一方面新生代中的对象多是临时对象,另一方面新生代空间中有一半是空闲的,所以只分的两成的空间。

    新生代 GC采用复制算法。在新生代空间中,内存空间分为两部分,分别为 From 空间和 To 空间。在这两个空间中,必定有一个空间是使用的,另一个空间是空闲的。新分配的对象会被放入 From 空间中,当 From 空间被占满时,新生代 GC 就会启动了。算法会检查 From 空间中存活的对象并复制到 To 空间中,如果有失活的对象就会销毁。当复制完成后将 From 空间和 To 空间互换,这样 GC 就结束了。如果垃圾回收时,存活的对象太多,To 空间的对象占比大小超过 25 %。在这种情况下,为了不影响到内存分配,会将对象从新生代空间移到老生代空间中,就会出现有些对象提前进入老生代的情况。

    当新生代中的对象经历过一次 Scavenge 算法后,会将对象从新生代空间移到老生代空间中。

    老生代 GC采用标记清除算法和标记压缩算法。老年代中主要存放存活时间较长的持久对象,这类对象数量较多。当老年代中的内存消耗超过一定限制时,会先启动标记清除算法,清除对象后会造成堆内存出现碎片的情况,当碎片超过一定限制后会启动压缩算法。在压缩过程中,将活的对象像一端移动,直到所有对象都移动完成然后清理掉不需要的内存。

    在 GC时,浏览器会停止响应其他操作,而一次GC可能需要几百毫秒才能完成。这就会导致一些性能上的问题。为了解决这个问题,2011 年,V8 从 stop-the-world(STW) 标记切换到增量标志。在增量标记期间,GC 将标记工作分解为更小的模块,可以让 JS 应用逻辑在模块间隙执行一会,从而不至于让应用出现停顿情况。在 2018 年,GC 技术又有了一个重大突破,这项技术名为并发标记。该技术可以让 GC 扫描和标记对象时,同时允许 JS 运行。

转载地址:http://zlbeo.baihongyu.com/

你可能感兴趣的文章
面试宝典之沟通能力
查看>>
RSA加密解密(无数据大小限制,php、go、java互通实现)
查看>>
ES6系列文章 模板字符串
查看>>
logrotate使用
查看>>
Trie树使用实例
查看>>
ELK 集群 + Redis 集群 + Nginx ,分布式的实时日志(数据)搜集和分析的监控系统搭建,简单上手使用...
查看>>
【Java并发编程的艺术】第二章读书笔记之synchronized关键字
查看>>
WePY为了兼容支付宝小程序,改了好几十行代码
查看>>
翻译:为Forge Viewer的 模型贴材质
查看>>
vue pomodoro (番茄钟) 组件 - 基于vue2.x
查看>>
TWaver可视化编辑器的前世今生(三)Doodle
查看>>
字节码及ASM使用
查看>>
重定向和伪静态在网站中的应用
查看>>
HTML5解决跨域方案之postMessage
查看>>
[LeetCode] Remove Nth Node From End of List
查看>>
Java人员正确使用 IntelliJ IDEA的方式
查看>>
reactjs前端实践|第三篇:TodoList示例事件、state、props、refs
查看>>
Java final常量“无法更新”的问题
查看>>
ES6之"let"能替代"var"吗?
查看>>
手摸手,带你用vue撸后台 系列一(基础篇)
查看>>