前言
总所周知,js是有垃圾回收机制的,大致分为标记清除和引用计数,目前主流浏览器都用的是标记清除。
定义
标记清除:垃圾回收器每个一段时候会扫描一次内存,这个时间很短。在扫描过程中,垃圾回收器会把内存中所有的变量加上标记,然后如果有你需要用到的内存,垃圾回收器就会把对应内存的标记删掉,之后将有标记的内存全部回收删除。这套机制就是垃圾回收机制,这个清理工作是高频操作。(通常全局变量是不会被自动回收的)
内存泄漏就是指由于疏忽或程序的某些错误造成未能释放的已经不再使用的内存的情况。简单来说就是一个变量已经不被使用,但任然存在的的内存中不被回收。这就是一种内存浪费,即内存泄漏。
一个很简单的例子
function f1() {
let a = new Array(10000)
let b = 3;
function fn2() {
let c = [1, 2, 3]
}
fu2()
return a;
}
let res = f1()
很容易的看出,f1中的局部变量b和f2中的局部变量c根本没有被用到,所以会被垃圾回收机制清除,f1中的a被return出去,又被全局变量res引用,所以不会1被清除,如果res没有被使用,并且其为全局变量,就造成了内存泄漏。
使用谷歌devTools查看当前内存使用情况
打开开发者工具,找到 performace 这一栏,可以看到其内部带着一些功能按钮,例如:开始录制按钮,刷新页面,手动进行垃圾回收按钮,如图。
我们简单录制一下百度页面,如图
从图中我们可以看到,在页面从零加载完成这个过程中, 有五条曲线图
- JS Heap 为 JS堆内存 (本期着重关注的点)
- Nodes DOM节点
- documents 文档
- Listeners 监听器,事件监听
- GPU memory GPU内存
再来看看开发者工具中 Memory 一栏,其主要是用于记录页面退内存的具体情况以及 js 退内存随加载时间线动态的分配情况,功能点如图
- Heap snapshot:堆快照,将某个时间点所有的内存分配情况拍一个快照,堆快照文件显示页面的 javascript 对象和相关 DOM 节点之间的内存分配</