以前对 javascript 的垃圾回收机制没有深入了解过。以为只是简单的标记清除法。即从根对象开始找它的引用,然后依次往后找它引用的引用,依次递归,将所有被引用的变量打上标记。然后在遍历完后,清除没有被标记的变量。

具体文章可以参考 mdn:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_Management

但是 javascript 中 v8 引擎中的垃圾回收机制比这个要稍微复杂一些。

什么是 v8 引擎

javascript 并不能被系统底层所能识别,需要有一个转换器将 js 转换成 CPU 所认识的汇编语言。 javascript v8 引擎就是这样的一种转换器,可以将 javascript 代码转换成不同架构 CPU 的所识别的汇编语言。但 v8 引擎并不仅仅起着编译的作用,还负责代码的执行和内存分配工作。

v8 引擎是 chrome 的。但是因为其出色的性能,因而被 nodejs 采用作为 js 解释器。

分代式垃圾回收机制

v8 中将内存分成两个区,一个是新区(young space)一个是旧区(old space)
新区要比旧区小
新区内存的最大值在 64 位和 32 位系统上分别是 32MB 和 16MB
(因此我们在使用 node 时,如果想要扩展 node 的内存大小可以使用 --max-old-space-size 和 --max-new-space-size 来调整新区和旧区的内存大小)

区分于新区和旧区的依据是:对象的存活时间
新区存放的对象存活时间较短,而旧区中存放的对象时间较长或常驻内存的对象。

在新区中采用 scavenge 策略

即将新区又分成两部分,一部分是闲置的叫做 To 空间,一部分是新区使用的内存叫做 From 空间。新区使用的内存会遍历一遍,检查活着的对象,然后将活着的对象复制到 To 空间中,将 From 空间清空,然后将 From 和 To 区对换。即可完成一次新区的垃圾回收。

在旧区中采用 mark-sweep 标记清除 和 mark-compact 标记整理

旧区中存活的对象较多,复制存活的对象效率会很低。并且如果旧区比较大,如果分成两个区会浪费一半的空间。因此在旧区中使用 mark-sweep 和 mark-compact
遍历堆中的对象,标记活着的对象。遍历完后进行清除未标记的。

这样清除了未标记的对象后,会又很多零碎(不连续)的内存空间,这样的碎片内存空间会对之后的内存分配造成问题。因为很可能出现一个很大的对象,这是所有的碎片空间都满足不了此次分配,就会提前触发垃圾回收,而这次回收是不必要的。

因此会在标记清除后移动存活对象的内存空间使其内存空间连续,这样就不存在零碎的内存空间。

垃圾回收的时机

为了避免垃圾回收机制运行过程中,javascript 运行改变内存。垃圾回收机制运行过程中javascript 停止运行。在垃圾回收完成后, javascript 继续执行应用逻辑。
在一次小垃圾回收只收集新区,由于新区默认配置得较小,且其中存活对象通常较小,所以即使停顿也影响不大。
但是旧区很大,且存活对象较多,停顿时间会很长影响性能。因此旧区进行优化:
增量标记: 将一次垃圾回收分成很多小步,每次做完一小步,就让 javascript 执行一会,垃圾回收和应用逻辑交替执行直到标记阶段完成。

参考:
v8引擎如何工作
js内存管理
chrome v8 garbage collect
《深入浅出node.js》

javascript 垃圾回收机制--分代式垃圾回收机制相关推荐

  1. 基于分代的垃圾回收算法

    以下均为摘要,摘要书籍<深入分析javaweb技术内幕> 1.如何检测垃圾 2.基于分代的垃圾回收算法 hotspot中使用的基于分代的垃圾收集方式 ------------------- ...

  2. 简介三种垃圾回收机制:分代复制垃圾回收,标记垃圾回收,增量垃圾回收

    一.分代复制垃圾回收 不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比 ...

  3. java gc g1_Java 分代式GC与G1算法

    前言:最近浏览了不少分代式GC和G1算法的文章,好多文章的知识点都比较分散,要几篇文章结合起来对比才能明白,特别是R大的文章,很精辟但不好理解,这里我就把我最近收集并结合自己理解的有关分代式GC和G1 ...

  4. 对比Ruby和Python的垃圾回收(2):代式垃圾回收机制

    本文由 伯乐在线 - 熊崽Kevin 翻译自 patshaughnessy.欢迎加入 技术翻译小组.转载请参见文章末尾处的要求. 对比Ruby和Python的垃圾回收(1) 上周,我根据之前在RuPy ...

  5. java垃圾回收 分代_Java-垃圾回收机制-通用的分代垃圾回收机制

    分代垃圾回收机制是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率.Java虚拟机将对象分为三种状态:年轻代.年老代.持久代.JVM将 ...

  6. java垃圾回收 分代_Java 垃圾回收机制 (分代垃圾回收ZGC)

    什么是自动 自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制.所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象:而未使用中的对象(未引用对象), ...

  7. 七种垃圾收集器和垃圾回收、分代收集、GCROOTS相关概念、GC如何判断一个对象可以被回收

    文章目录 垃圾收集器概述 垃圾回收算法 1)标记-清除算法(Mark-Sweep)(DVM 使用的算法) 2)复制算法(Copying) 3)标记-整理算法(Mark-Compact) 4)分代收集( ...

  8. Garbage First (G1) GC垃圾回收器:区域化分代式【图文】

    1.问:既然我们已经有了前面几个强大的GC,为什么还要发布Garbage First (G1) GC? 答:(1)原因就在于应用程序所应对的业务越来越庞大.复杂,用户越来越多,没有GC就不能保证应用程 ...

  9. 一文详解,jvm内存分代与垃圾回收原理

    jvm运行时数据区 Java程序启动后,本质上就是启动一个jvm进程,jvm会将自己管理的内存划分为几个区域,每个区域都有自己的用途.在程序运行时的内存区域主要可以划分为五个,分别是:方法区.堆.虚拟 ...

最新文章

  1. FreeMarker 自动转义和格式化HTML和XML输出,预防xss
  2. Algorithms_二叉树二分搜索树初探
  3. Spring Session实战
  4. 用SD卡下载uboot、linux内核和文件系统
  5. Linux 代码格式化工具 indent
  6. oracle 出参类型定义,Oracle plsql出参clob类型的操作
  7. boost 获取日期时间
  8. android arcgis多变形边框颜色,ArcGIS制图技巧—边框的选择
  9. 嵌入式工作笔记0003---认识LCD显示器
  10. linux下使用SSH实现端口映射
  11. PC端输入法双拼皮肤分享
  12. Axure RP 9.0.0.3687 正式版
  13. Cisco Devnet CCNA【200-901】题库稳定
  14. 力扣刷题-动态规划算法3:完全背包问题
  15. [转]IDE 、SATA、SCSI 的区别
  16. win10资源管理器打开一直正在处理文件加载不出来,桌面图标不加载
  17. c语言编程数组例题,c语言编程有关数组的几道例题.docx
  18. 如何创建dblink
  19. C++添加防火墙例外——检测目标程序不在例外列表时才进行添加,防止重复添加
  20. 【知识图谱】 一个有效的知识图谱是如何构建的?

热门文章

  1. 'unicodeescape' codec can't decode bytes in position 16-17: malformed \N character escape
  2. php下正则替换多个br /
  3. ubuntu右键在当前位置打开终端
  4. 青龙羊毛——灰兔掌赚吹牛逼
  5. jq输出文本_jQuery获取文本节点之 text()/val()/html() 方法区别
  6. java javaw javaws MC_java和 javaw 以及 javaws的區別
  7. linux下实现dns服务器,实现Linux操作系统下DNS服务器的搭建
  8. Git使用汇总之暂存区工作区撤销和删除
  9. linux 添加动态链接库路径
  10. php 字母转换成小写字母,PHP中将大写字母转换为小写字母的函数是_________