关于前端内存泄漏

JavaScript/前端
471
0
0
2022-04-06

前端的学习已经进入了一个艰难的上升期,越来越发现自己学习的东西还多得多,需要掌握的知识面宽广了很多,知识点需要理解的深度也加深了很多。今天看到前端内存泄漏相关,自己总结总结,也便于自己以后学习记忆。由于经验所致,必然会有不足之处,欢迎指正!

什么是内存

内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。

什么是内存泄漏

内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。 说白了就是 不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。

看完上面的解释,脑海中就会有一点概念,计算机正常运转会用到内存,内存像是一个中转站,他把你暂存的数据,马上就会用到的数据存储在这,以让你更快捷方便的使用, 那你肯定会想到一个问题,暂存的数据到底哪些该存储在这里,存储的东西不会一直在这,又是怎么消失的呢?

在我的理解,前端开发中,全局的、被引用的对象就会被保存在内存中。比如我们常见的闭包:

function leak(arg) {
    this.arg = arg;
}
function test() {
    var l1= new leak('It is a leak');
    document.body.addEventListener('click', function() {
        l1.arg = 'Here you are!'
    })
}
test()

很明显,l1被闭包环境引用,无法被回收

那么浏览器是怎么判断一个对象是不是该被垃圾回收了呢

对前端开发来说只需要理解'引用计数法'就可以了 语言引擎有一张"引用表",保存了内存里面所有的资源(通常是各种值)的引用次数。如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放。

代码层面内存泄露的原因

  1. 循环引用
  2. 闭包
  3. 全局变量
  4. 没有清理的DOM元素引用
  5. 被遗忘的定时器以及其中的引用

可能造成了内存泄漏要怎么排查

  1. 我们可以使用chrome浏览器调试工具中的内存快照,点击左上角灰色原点就可以保存一份快照,记录此时内存使用情况 可以看到代码中明显的l1对象被引用导致无法释放,在快照中我们也看到了一个leak实例在内存中。通过见=简单分析就可以知道是哪块代码出了问题

关于前端内存泄漏

关于前端内存泄漏

2. 如果是在Node环境下,可以用Node提供的process.memoryUsage()方法来检查内存泄露:具体方法可以参考阮一峰的例子:

https://github.com/ruanyf/es6tutorial/issues/362#issuecomment-292451925

  • rss (resident set size) : 所有内存占用,包括指令区和堆栈。
  • heapTotal : "堆"占用的内存,包括用到的和未用到的。
  • heapUsed : 用到的堆。
  • external : V8引擎内部C++对象占用的内存。

判断内存泄露以heapUsed为准。

如何处理

  1. 避免循环引用等发生源
  2. 变量导致的内存泄露,将变量清除 a = null
  3. 事件监听导致的内存泄露,监听后移除
作者:天微蔚蓝
链接:https://juejin.im/post/5c6663a85188252a160efa3c
来源:掘金