什么是内存泄露
内存泄露是指你「用不到」(访问不到)的变量,
依然占居着内存空间,不能被再次利用起来。
什么会导致内存泄露
常见的内存泄露
意外的全局变量引起的内存泄露
function leak(){
leak= "xxx"; //leak成为一个全局变量,不会被回收
}
没有清理的DOM元素引用
比如拿到DOM的引用,给他绑定了事件,
又偷偷把dom给销毁了
被遗忘的定时器
IE7/8引用计数使用循环引用产生的问题
Vue 为例,通常有这些情况:
监听在 window/body 等事件没有解绑
绑在 EventBus 的事件没有解绑
Vuex 的 $store,watch 了之后没有 unwatch
使用第三方库创建,没有调用正确的销毁函数
解决办法:beforeDestroy 中及时销毁
绑定了 DOM/BOM 对象中的事件 addEventListener ,removeEventListener。
观察者模式 $on,$off处理。
如果组件中使用了定时器,应销毁处理。
如果在 mounted/created 钩子中使用了第三方库初始化,对应的销毁。
使用弱引用 weakMap、weakSet
怎样避免内存泄露
1)减少不必要的全局变量,或者生命周期较长的对象,
及时对无用的数据进行垃圾回收;
2)注意程序逻辑,避免“死循环”之类的 ;
3)避免创建过多的对象 原则:不用了的东西要及时归还。
答题思路
浏览器怎么进行垃圾回收?
答题思路:什么是垃圾、怎么收垃圾、什么时候收垃圾。
浏览器中不同类型变量的内存都是何时释放?
答题思路:分为值类型、引用类型。
Javascritp 中类型:值类型,引用类型。
引用类型
在没有引用之后,通过 V8 自动回收。
值类型
如果处于闭包的情况下,要等闭包没有引用才会被 V8 回收。
非闭包的情况下,等待 V8 的新生代切换的时候回收。
哪些情况会导致内存泄露?如何避免?
答题思路:内存泄露是指你「用不到」(访问不到)的变量,
依然占居着内存空间,不能被再次利用起来。
weakMap weakSet 和 Map Set 有什么区别?
答题思路:WeakMap、WeakSet 弱引用,解决了内存泄露问题。
使用闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,
所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函
数当作对象(object)使用,把闭包当作它的公用方法(Public Method)
,把内部变量当作它的私有属性(private value),这时一定要小心,
不要随便改变父函数内部变量的值。
闭包会导致内存泄露吗?
顺便说一个我在了解垃圾回收之前对闭包的误解。
闭包会导致内存泄露吗?正确的答案是不会。
内存泄露是指你「用不到」(访问不到)的变量,
依然占居着内存空间,不能被再次利用起来。
闭包里面的变量就是我们需要的变量,不能说是内存泄露。
这个误解是如何来的?因为 IE。IE 有 bug,IE 在我们使用完闭包之后,
依然回收不了闭包里面引用的变量。这是 IE 的问题,不是闭包的问题