V8中的垃圾回收机制

1.JavaScript中的垃圾收集

      1.程序的运行需要内存,只要程序需要,操作系统就必须提供内存。

      2.JavaScript使用自动内存管理,这被称为垃圾回收机制garbage collector

     3. 优点:简化开发,节省代码

      4.缺点: 无法完整的掌握内存的分配与回收的具体过程

1.1.NodeJS中的内存管理

     如果不再用到的内存没有及时释放,就叫做内存泄漏

1.2 V8内存管理

    1.2.1 V8内存限制

         在 64 位操作系统可以使用 1.4G 内存
         在 32 位操作系统中可以使用 0.7G 内存
   

    1.2.2 V8内存管理

          JS对象都是通过V8进行分配管理内存的

           process.memoryUsage 返回一个对象,包含了 Node 进程的内存占用信息
   
    
rss resident set size ):所有内存占用,包括指令区和堆栈。
heapTotal 占用的内存,包括用到的和没用到的
heapUsed :用到的堆的部分。判断内存泄漏,以 heapUsed 字段为准
external V8 引擎内部的 C++ 对象占用的内存

 

1.2.3 为何限制内存大小

因为V8的垃圾收集工作原理导致的, 1.4G内存完全一次垃圾收集需要1秒以上

这个暂停时间成为 Stop The World , 在这个期间,应用的性能和响应能力都会下降

 

1.2 4 如何打开内存限制

一旦初始化成功,生效后不能再修改
–max-new-space-size ,最大 new space 大小,执行 scavenge 回收,默认 16M ,单位 KB
–max-old-space-size ,最大 old space 大小,执行 MarkSweep 回收,默认 1G ,单位 MB
 
node --max-old-space-size=2000 app.js 单位是M
node --max-new-space-size=1024 app.js 单位是kb

2. V8的垃圾回收机制

V8 是基于分代的垃圾回收
不同代垃圾回收机制也不一样
按存活的时间分为新生代和老生代
 

2.1 分代

年龄小的是新生代,From区域和To区域两个区域组成

   64位系统里,新生代内存是32M,From区域和To区域各占用16M

   32位系统里,新生代内存是16M,From区域和To区域各占用8M

 年龄大的是老生代,默认情况下

    64为系统下老生代内存是1400M

    32为系统下老生代内存是700M

2.2引用计数

语言引擎有一张引用表,保存了内存里面所有的资源的引用次数。
如果一个值的引用次数是 0 ,就表示这个值不再用到了,因此可以将这块内存释放。
 
 
function Person(name){
    this.name = name
}

let p1 =  new Person('tengxun')
let p2 =  new Person('huawei')

let arr = [p1]

setTimeout(function(){
    p1 = null;
    p2 = null;
},3000)

setTimeout(function(){
    arr = null
},10000);

let arr = []
setInterval(function(){
    let obj = {}
    for(let i=0;i<1000000;i++){
        obj[i] = i
    }
    arr.push(obj)
},500)

function Person(name){
    this.name = name;
}

let set = new Set();
let weakset = new WeakSet();
let p1 = new Person('tengxun')
let p2 = new Person('huawei')
set.add(p1)
weakset.add(p2)
p1 = null
p2 = null

2.2 新生代垃圾回收 

新生代区域一分为二,每个 16M ,一个使用,一个空闲
开始垃圾回收的时候,会检查 FROM 区域中的存活对象,如果还活着,拷贝到 TO 空间,完成后释
放空间
完成后 FROM TO 互换
新生代扫描的时候是一种广度优先的扫描策略
新生代的空间小,存活对象少
当一个对象经历过多次的垃圾回收依然存活的时候,生存周期比较长的对象会被移动到老生代,
这个移动过程被成为晋升或者升级
经过 5 次以上的回收还存在
TO 的空间使用占比超过 25% ,或者超大对象
 
 

2.3 老生代

mark-sweep( 标记清除 ) mark-compact( 标记整理 )
老生代空间大,大部分都是活着的对象 ,GC 耗时比较长
GC 期间无法响应, STOP-THE-WORLD
V8 有一个优化方案,增量处理,把一个大暂停换成多个小暂停 INCREMENT-GC
 
 

 

2.3.1 mark-sweep(标记清除)

标记活着的对象,随后清除在标记阶段没有标记的对象,只清理死亡对象
问题在于清除后会出现内存不连续的情况,这种内存碎片会对后续的内存分配产生影响
如果要分配一个大对象,碎片空间无法分配

 

2.3.2 mark-compact(标记整理)

标记死亡后会对对象进行整理,活着的对象向左移动,移动完成后直接清理掉边界外的内存

 

2.3.3 incremental marking 增量标记

以上三种回收时都需要暂停程序执行,收集完成后才能恢复, STOP-THE-WORLD 在新生代影响
不大,但是老生代影响就非常大了
增量标记就是把标记改为了增量标记,把一口气的停顿拆分成了多个小步骤,做完一步程序运行
一会儿,垃圾回收和应用程序运行交替进行,停顿时间可以减少到 1/6 左右
包括垃圾回收的占用时间
 
 
 
v8垃圾清理机制初步整理,欢迎留言讨论。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值