Nodejs内存管[Mark-Sweep算法][Mark-Compact]

内存控制

Mark-Sweep & Mark-Compact

对于老生代的对象,存活对象占较大的比重,采用scvenge方法会存在如下问题

1. 存活对象较多,复制存活对象的效率很低
2. 浪费一半空间的问题

因此v8在老生代中主要采用了Mark-Sweep和Mark-Compact相结合的方式进行垃圾回收
Mark-Sweep不将内存空间划分为两半,不存在浪费一半空间的行为。Mark-Sweep在标记阶段遍历堆中的所有对象,标记活着的对象,在随后的清除阶段,只清除没有标记的对象。对比Scanvenge.Scavenge中只复制活着的对象,而Mark-Sweep只清理死亡的对象。活对象在新生代中只占较小的部分,死对象在老生代中只占较小的部分。
Mark-Sweep最大的问题是在进行一次标记清楚回收之后,内存空间会出现不连续的状态。这种内存碎片会对后续的内存分配造成问题。
Mark-Compact是标记整理,在Mark-Sweep之后演变回来的。差别在于对象在标记为死亡之后,在整理的过程中,将获得对象往一侧移动,移动完成hi后,直接清理掉边界外的内存。
在这里插入图片描述

在这里插入图片描述

全暂停停顿和增量标记

为了避免出现JavaScript应用程序和垃圾回收器不一致的情况,垃圾回收的三种基本算法都需要将应用程序暂停下来,等待执行完垃圾回收之后,在恢复应用逻辑,这种行为被称为全暂停停顿
为了降低全堆垃圾回收带来的停顿时间,v8在2011年引入了增量标记的算法。增量标记将垃圾回收的执行过程分为多个小阶段,在每个小阶段中,垃圾回收器只标记一部分存活的对象,然后将标记的结果进行合并,最后一次性将存活的对象复制到新的内存空间中。
javascript还引入了延迟清理增量式整理
在这里插入图片描述

以上三种算法的对比

在这里插入图片描述

在v8的垃圾回收过程中,会输出一些日志信息,可以通过`--trace-gc`来开启垃圾回收日志的输出。
$node --trace-gc

高效使用内存

在v8面前,开发者需要让垃圾回收机制更高效的工作

作用域

在JavaScript中,能形成作用域的有函数调用,with以及全局作用域

var foo = function() {
    val local = {}
}

在函数调用的时候会形成响应的作用域,函数执行完成之后,作用域会销毁。函数作用域中声明的局部变量分配在该作用域上,随着作用域的销毁而销毁。在这个实例中,对象非常小,会被分配在新生代中的from空间中,在作用域释放之后,局部变量失效,引用的对象会在下次垃圾回收的时候被释放

标识符查找
var bar = function () {
    console.log(local)
}

javascript在执行时候回去查找变量定义。先查找当前作用域,如果在当前作用域中没有办法找到该变量的声明,就会像上级作用域中去找。直到找到为止。

作用域链
var foo = function() {
    var local = 'local var'
    var bar = function() {
        var local = 'another var'
        var baz =function () { 
            console.log(local)
        }
    baz()
    }
bar()
}
foo()

在这里插入图片描述

变量的主动释放

如果变量是全局变量,由于全局作用域需要直到进程退出才能释放,此时导致引用的对象常驻内存,如果需要释放常驻内存的对象,可以通过delete操作来删除引用关系,将变量重新赋值,将旧的对象脱离关系。

gloval.foo = "I am global object"
console.log(global.foo)
delete global.foo // 
global.foo = undefined
console.log(global.foo) // undefined

闭包

闭包是JavaScript的高级特性,利用他可以产生很多巧妙的效果,问题在于,一旦有变量引用则个中间函数,这个中间函数不会发生释放,同时也会使得原始的作用域不会得到释放。作用域中产生的内存占用也不会得到释放

小结

在JavaScript执行中,无法立即回收的内存有闭包和全局变量引用情况。

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值