这是一篇关于前端内存知识的博文,主要讲述了什么是内存?内存生命周期,内存泄漏,解决与避免方案。
什么是内存?
但是在JavaScript中我们无需在意内存的读写操作,因为这些Chrome都会帮我们处理好,我们需要做的就是避免变量或属性不能被正常回收即可。
生命周期
无论是什么程序语言,大家对内存的生命周期规定基本一致。
- 分配你所需要的内存
- 使用分配到的内存(读、写)
- 不需要时将其释放\归还
分配 使用 释放
内存泄漏
现代的高级语言绝大部分都是具备自动GC的能力的,如果发生了内存的泄漏,最大可能是由于疏忽或错误造成程序未能释放已经不再使用的内存导致的。
如果内存不需要的时候,如果此时没有被释放,那么就会造成内存泄漏了。
简单总结一下:内存泄漏就是无用的变量占据着内存,无法释放归还内存。严重的时候甚至造成页面卡顿,崩溃。
内存回收
内存回收我们一般也称为垃圾回收即GC(Garbage Collection)。
内存泄漏一般都是发生在这一步,虽说现在的GC机制已经能回收绝大部分垃圾内存,但是还是存在回收不了的情况,此时我们就需要去手动清理。
下面说一下两种常见的GC算法
引用计数法
该算法是什么简单,如果当前对象没有被其他任何对象使用,那么此时该对象就能被回收。
该算法存在一个限制:无法理解循环引用,比如下面的例子。
function f(){
var o = {};
var o2 = {};
o.a = o2; // o 引用 o2
o2.a = o; // o2 引用 o
return "azerty";
}
f();
两个对象被创建,并互相引用,形成了一个循环。它们被调用之后会离开函数作用域,所以它们已经没有用了,可以被回收了。然而,引用计数算法考虑到它们互相都有至少一次引用,所以它们不会被回收。
标记清除算法
通俗来讲就是对正在使用的变量进行标记,如果正在使用标记为1 未使用标记为0,GC在回收的时候发现该对象标记为0,那么就对该对象进行回收操作。
JavaScript的内存分配
JavaScript不需要程序员手动分配内存,绝大多数情况下都能够自动完成内存的分配,使用,和回收等操作。
JavaScript对内存的管理机制是和内存的生命周期一一对应的,分配,使用,释放。
1.记住JavaScript 定义变量就会自动分配内存的。我们只需了解 JavaScript 的内存是自动分配的就足够了。
2.使用值的过程实际上是对分配内存进行读取与写入的操作。读取与写入可能是写入一个变量或者一个对象的属性值,甚至传递函数的参数。
内存泄漏场景
JavaScript 的内存回收机制虽然能回收绝大部分的垃圾内存,但是还是存在回收不了的情况。程序员要让浏览器内存泄漏,浏览器也是管不了的。
全局变量
// 在全局作用域下定义
function count(number) {
// basicCount 相当于 window.basicCount = 2;
basicCount = 2;
return basicCount + number;
}
这里就得突出eslint的重要性了。
被遗忘的计时器
新手常犯的错误之一。
mounted() {
setInterval(function() {
// 轮询获取数据
this.refresh()
}, 2000)
},
当一个计时器启动的时候,无论外部怎么销毁内部是无法清理的,我们需要调用专门的清除函数去手动清理。
mounted() {
this.refreshInterval = setInterval(function() {
// 轮询获取数据
this.refresh()
}, 2000)
},
beforeDestroy() {
clearInterval(this.refreshInterval)
},
上面就是一个比较合适的逻辑了clearInterval完成对setInterval的清理。
被遗忘的事件监听器
这也是作为内存泄漏的高频问题同样是需要用户去手动卸载的。
例如:
<template>
<div></div>
</template>
<script>
export default {
mounted() {
window.addEventListener('resize', () => {
// 这里做一些操作
})
},
}
</script>
组件销毁的时候,resize 事件还是在监听中,里面涉及到的内存都是没法回收的(浏览器会认为这是必须的内存,不是垃圾内存)
这里我们需要window.removeEventListener('resize', this.resizeEventCallback)去完成对Listener的卸载。
其他
Set,Map,订阅发布事件监听器,闭包,脱离 DOM 的引用等。
泄漏定位
1)通过google的开发者工具,切换到Performance选中Memory,点击录制。
如果内存平稳,不再递增,那么就是正常的,如果出现一直递增那么就有可能出现内存泄漏。
2)查找位置,利用Memory录制快照,查找Shallow Size比较大的进行分析。
参考资料
深入理解JavaScript内存泄漏
内存管理
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!