什么是内存泄漏?

什么是内存泄漏?
[参考简书0](https://www.jianshu.com/p/fe5e6e5d3d33)
内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。

无用的对象占据着内存空间,使得实际可使用内存变小,形象地说法就是内存泄漏了。

不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)

- 内存溢出(Out Of Memory):“你内存一共就剩1MB,非要存个1GB的数据,存小点不行吗?要不再加点内存空间好不好,还存,还存溢出了昂,一库一库~”

- 内存泄漏(Memory Leak):“你声明了一个又一个局部引用变量,都用完了还不让垃圾回收,空间都被占用光了晓得不啦,快点把这块用不到的内存给老子释放了!”

全局变量在页面关闭之前是不会被浏览器所回收的。它们就成了占用内存的冗余代码。

 发生内存泄漏的场景:
[参考简书1](https://www.jianshu.com/p/6eaa50cb0818)
1.循环引用

- 第一种:多个对象循环引用

var a=new Object;
var b=new Object;
a.r=b;
b.r=a;

- 第二种:循环引用自己

var a=new Object;
a.r=a;

 

2.闭包 在IE浏览器中会形成内存泄漏。为早期IE是使用C/C++引擎,他们的垃圾回收机制是通过引用计数这种方式。所以闭包中的引用一直不清零就会形成泄漏。

3.全局变量在页面关闭之前都不会被释放,存在内存泄漏,但使用严格模式可以避免。

4.没有清理的DOM元素引用。比如将DOM节点引用存储起来,再删掉DOM节点,但是引用未清理。它依然存在于内存中。**/** DOM 节点绑定了事件, 但是在移除的时候没有解除事件绑定,那么仅仅移除 DOM 节点也是没用的

var element = {
shotCat: document.getElementById('shotCat')
};

document.body.removeChild(document.getElementById('shotCat'));
// 如果element没有被回收,这里移除了 shotCat 节点也是没用的,shotCat 节点依然留存在内存中.

 

解决方法:[移除绑定的事件](https://www.jianshu.com/p/64e8b60a97d9)

//解决方法:清除绑定的事件,即可从内存中移除

<div id="container"></div>
$('#container').bind('click', function(){
console.log('click');
});

$('#container').off('click').remove();
//移除绑定的事件

 

5.被遗忘的定时器**setInterval**以及其中的引用。但是 **setTimeout** ,它计时结束后它的回调里引用的对象占用的内存是可以被回收的. 当然有些场景 setTimeout 的计时可能很长, 这样的情况下也需要考虑内存泄漏问题。.

内存泄漏的识别方法
1. 使用快捷键 F12 或者 Ctrl+Shift+J 打开 Chrome 浏览器的「开发者工具」。
2. 选择 Performance(老版为Timeline) 选项卡,在 Capture 选项中,只勾选 Memory。
3. 设置完成后,点击最左边的 Record 按钮,然后就可以访问网页了。
4. 打开一个网站,例如:www.taobao.com当网页加载完成后,点击 Stop,等待分析结果。
5. 然后在 Chart View 上寻找内存急速下降的部分,查看对应的 Event Log,可以从中找到GC 的日志。


内存泄漏避免策略:
1. 减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收**(即赋值为null**); a = null
2. 注意程序逻辑,避免“死循环”之类的 ; 避免循环引用等发生源
3. 避免创建过多的对象 原则:不用了的东西要记得及时归还。
4. 减少层级过多的引用
5. 事件监听导致的内存泄露,监听后移除

-----------------------------------

补充:VUE v-if指令产生的内存泄露:**

就是非常常见的比如我们通过v-if删除了父级元素,但是并没有移除父级元素里的dom片段。通常产生于使用第三方库的时候,比如下面的示例中,我们加载了一个带有非常多选项的选择框,然后我们用到了一个显示/隐藏按钮,通过一个 v-if 指令从虚拟 DOM 中添加或移除它。这个示例的问题在于这个 v-if 指令会从 DOM 中移除父级元素,但是我们并没有清除由第三方库 新添加的 DOM 片段,从而导致了内存泄漏。

posted @ 2020-05-25 15:17  悦耳pn  阅读(906)  评论(0编辑  收藏  举报