内存泄漏相关实践

54 阅读3分钟

参考文章:blog.csdn.net/qq_42690194…

在node环境执行下述命令,开启垃圾回收:

node --expose-gc    /--expose-gc 表示允许手动执行垃圾回收机制

方式1(内存泄漏版):

下面是出现内存泄漏的版本:

// 手动执行一次垃圾回收保证内存数据准确
> global.gc()
undefined// 查看当前占用的内存,主要关心heapUsed字段
> process.memoryUsage()
{
  rss: 27512832,
  heapTotal: 6250496,
  heapUsed: 4676368,
  external: 967705,
  arrayBuffers: 100550
}
​
// 执行代码
> function A() {
...     let a = new Array(1000000)
...     a[0] = 12
...     let b = () => {
.....         console.log('方式1:a[0]', a[0]);
.....     }
...     return b
... }
undefined
> let B = A();
undefined
> B()
方式1:a[0] 12
undefined
    
// 执行垃圾回收
> global.gc()
undefined
// 查看内存数据,发现heapUsed字段超出许多,说明内存已经泄漏,查看代码,判断是a变量没有被回收
> process.memoryUsage()
{
  rss: 36499456,
  heapTotal: 14520320,
  heapUsed: 13166712,
  external: 964177,
  arrayBuffers: 215241
}
​
// 清除B对变量a的引用
> B = null
null
// 再次执行垃圾回收
> global.gc()
undefined
// 查看内存数据,发现heapUsed大幅下降,与初始值接近,有些许浮动属正常现象,全局仍有B变量为null,且内存数据会随时间逐渐增长
> process.memoryUsage()
{
  rss: 29171712,
  heapTotal: 6774784,
  heapUsed: 5897480,
  external: 964208,
  arrayBuffers: 297166
}

以下是上述出现内存泄漏的代码实例:

// 方式1 - 内存泄漏
function A() {
    // 初始化一个长度为1000000的数组,使内存数据变化更明显
    let a = new Array(1000000)
    a[0] = 12
    let b = () => {
        console.log('方式1a[0]', a[0]);
    }
    return b
}
let B = A();
B()

方式2(无内存泄漏版):

稍作修改,实现一个不存在内存泄漏的版本,先上代码:

// 方式2 - 不会内存泄漏
function A() {
    let a = new Array(1000000)
    a[0] = 13
    function B() {
        console.log('方式2a[0]', a[0]);
    }
    B()
}
A();

实际运行后,结果如下:

// 同样,先手动执行一遍垃圾回收,保证数据准确性
> global.gc()
undefined
// 记录内存数据初始值
> process.memoryUsage()
{
  rss: 27619328,
  heapTotal: 6774784,
  heapUsed: 4635304,
  external: 964863,
  arrayBuffers: 92356
}
​
//执行代码
> function A() {
...     let a = new Array(1000000)
...     a[0] = 13
...     function B() {
.....         console.log('方式2:a[0]', a[0]);
.....     }
...     B()
... }
undefined
> A();
方式2:a[0] 13
undefined
    
//执行垃圾回收
> global.gc()
undefined
//查看内存数据,发现heapUsed字段数值相较初始变化不大,与方式1形成鲜明对比,故此得出此代码不存在内存泄漏
> process.memoryUsage()
{
  rss: 28307456,
  heapTotal: 6774784,
  heapUsed: 5078312,
  external: 964182,
  arrayBuffers: 182472
}

总结:实践出真知,通过简单的例子直观感受内存泄漏,加深印象。