(备忘)V8的垃圾回收机制

一、背景

1、V8的内存限制

在node中通过JavaScript使用内存是会发现只能使用部分内存(64位系统约为1.4GB,32位系统约为0.7GB)。在这样的限制下,将会导致的node无法直接操作大内存对象,比如无法将一个2G的文件写入内存中进行字符串分析处理,即使物理内存有32GB。这样子在单个node进程下,计算机的内存资源会无法得到充分使用。

造成这个问题的主要原因是Node是基于V8构建的,所以Node使用JS对象是通过V8自己的方式来进行分配和管理的。在V8中JS对象都是通过堆进行分配,而这个内存限制主要是因为V8的垃圾回收机制。

2、扩大内存方式

内存限制可以通过下列的方式来扩大:

node --max-old-space-size=1700 test.js //单位是MB,扩大老生代内存大小
node --max-new-space-size=1024 test.js //单位MB,设置新生代的内存大小

二、垃圾回收

1、简介

V8的垃圾回收机制是基于分代式垃圾回收机制,因为没有哪一种垃圾回收机制能胜任所有场景,所以分不同情况使用不同垃圾回收机制。分代式指的是新生代和老生代,新生代中的对象为存活时间比较短的对象,使用scavenge算法,老生代的对象为存活时间较长或者常驻内存的对象,适应Mark-Sweep(标记清除)和Mark-Compact(标记整理)算法。

2、scavenge算法

主要是把在from块里存放的对象,垃圾回收启动时,复制存活的对象到to空间,然后清理掉剩下的对象,然后把from和to空间调转,其中每次复制对象前,会根据存活对象的地址判断其是否已经经过一次scavenge了,有的话就当做是老对象移动到老生代存储区,如果没有会检查to空间的已存放空间是否超过25%以上了,有的话,把剩下的存活对象都移到老生代存储区;(在新生代里使用这个算法的原因是因为新生代的活对象比较少)

3、Mark-Sweep

用来标记要清理的死对象,也就是给死对象打标记,然后进行清除(因为在老生代里死对象比较少)

4、Mark-Compact

在Mark-Sweep的基础上演变而来的,用来整理空间,也就是把存活对象往一端移动,然后把直接清理掉边界外的空间(因为Mark-Sweep清理后留下来的空间比较零碎,不好使用,需整理)

5、算法比较

算法scavengeMark-SweepMark-Compact
速度最快中等最慢
空间开销双倍空间(无碎片)少(有碎片)无(无碎片)
是否移动对象

6、优化算法

由于的以上三种算法的垃圾回收会使应用逻辑暂停下来,待执行完垃圾回收再恢复执行应用逻辑,这种行为称为“全停顿”,新生代的配置内存较小且存活对象少,所以scavenge算法对全停顿影响不大,但是老生代因为配置的内存较大,且存活对象多,所以造成的“全停顿”比较严重,所以为了解决这个问题,引入了incremental-marking(增量标记)、

  •   incremental-marking:是为了较少因为Mark-sweep带来的全停顿(垃圾回收算法阻塞了应用逻辑的执行)过长而使用的算法,可以把标记拆分成小“步进”和应用逻辑执行交替执行,直到标记完成;
  • lazy-sweeping:延迟清理,也就是增量式的清理标记后的对象;
  • incremental-compact:增量式整理,把整理的动作的做到和应用逻辑交替执行,也是为了减少全停顿时间。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值