巧用 devtool 检测/排查内存泄漏总结 🤔
前言
你能学到🍗
node.js
这里略讲一下,不是重点
如果是 node 环境下,
我们可以使用 Node 提供的process.memoryUsage方法。
process.memoryUsage
返回一个对象,包含了 Node 进程的内存占用信息。该对象包含五个字段
rss (resident set size)
:所有内存占用,包括指令区和堆栈。heapTotal
:"堆"占用的内存,包括用到的和没用到的。heapUsed
:用到的堆的部分。external
:V8 引擎内部的 C++ 对象占用的内存。arrayBuffers
:分配给ArrayBuffers和SharedArrayBuffers
的内存,包括所有Node.js
的Buffers
。
单位是字节
判断内存泄漏主要用heapUsed
,而这个方法主要是在Node
环境下,所以我们这里不做实操了
除了命令行,我们还可以利用 开发者工具~(本文主要讲这个,实操也只有这个~)
先了解一下 Chrome devtool🔨
很多人应该还没怎么用过开发者工具做这些东西,这里先将一下相关的按钮和图形代表的意思,在后面实操会带着具体操作~
性能 Performance🚀
f12
打开开发者工具,选择性能(Performance
)
当你想进行测量时,点击录制,然后进行操作正常的页面点击等操作就行了,配合手动垃圾回收,最后结束录制查看内存情况就好了
内存 Memory🍱
时间轴上的分配插桩
当你想进行测量时,点击录制,然后进行操作正常的页面点击等操作就行了,就可以看到一些柱子,有蓝色有灰色,蓝色的可能会变成灰色。
- 蓝色表示当前占用着的内存
- 变为灰色则表示内存已经被释放
堆快照
前面的都只是查看是否有内存泄漏,这个可以抓取两份快照,查看占用内存的对象到底是啥,然后我们可以借助这些信息来抓住可恶的内存小偷。
具体使用看下面的实操环节~
demo 准备🌰
index.html
<div id="root">
<button>button</button>
</div>
<script src="./index.js"></script>
index.js
document.querySelector("button").addEventListener("click", function () {
let big = new Array(999999);
// console.log(big);
});
实操🪐
性能🛬
操作
我们打开 index.html
,
- 打开开发者工具-性能
- 点击录制
- 先手动垃圾回收一下清空初始值
- 接着点击三下 button
- 接着手动垃圾回收一下试试
- 最后结束录制
效果
可以看到我们点击三次 button,JS 堆
阶梯上升,并且最后手动内存回收后仍然存在。这正是因为点击事件中创建的数组都被console.log
保存了下来导致无法回收
注释掉的效果
document.querySelector("button").addEventListener("click", function () {
let big = new Array(999999);
//console.log(big); // 把这行代码注释掉
});
你可以将console.log
注释掉,之后进行和上面一样的操作,再看看效果
可以看到每次new Array
之后,会先将之前的内存销毁,并且最后手动垃圾回收之后,内存占用与初始值相比基本平稳,也就是说没有内存泄漏了~
内存分配插桩🍳
操作
操作上基本和上面的一样,具体可看动图
效果
可以看见每次点击按钮都会出现一个蓝色柱子,并且不会变灰。也就是出现了被占用的内存但是不会被回收掉
注释掉的效果
还是和上面操作一样,将console.log
语句注释掉
可以看见出现蓝色柱子后(除了初始的那一条)很快就会变为灰色,说明之前的内存已经被清除释放~
内存堆快照🌭
我们一开始先什么都不操作录制一份堆快照,然后再点击三次再录制一分堆快照。
现在就得到了堆快照1
和堆快照2
比较
然后我们选择与快照1比较对比内存分配,按照大小从大到小排序
可以看见罪魁祸首是数组
控制
再到控制里看一下,大小从大到小排序
可以看见确实是console.log
的锅~
GC 就是 Garbage Collector),垃圾回收,GC root 就是垃圾回收器的对象
总结⛵
是否有案情(是否有内存泄漏)🤔
- 内存占用阶梯式上升,有案情
- 内存占用平稳,无案情
寻找凶手(哪里有内存泄漏)🤔
根据内存查看、比对内存堆快照
当然,这里 demo 例子比较简单,所以能比较轻松地查看内存泄漏清空。
实际上,这些工具能看见的内容相对与代码直接报错等排查会少得多,或者说“难看”得多。
这些工具大部分时候都是没法直接给你答案,告诉你谁是元凶。(不然他们为啥不直接warning
或者error
呢)
他只能提供部分内存信息,可能会告诉你哪些是嫌疑犯,甚至大部分时候这些信息都很难找,因为有时会嵌套地很深
而你需要靠这些信息和自己写代码的经验来排查凶手~
预防
其实排查内存泄漏真的是挺麻烦的~ 所以写代码的时候一定要注意啊,如果你还不太了解出现内存泄漏的场景,可以看看下面的推荐阅读~
推荐阅读
文中措辞、知识点、格式如有疑问或建议,欢迎评论~你对我很重要~ 🌊如果有所帮助,欢迎点赞关注,一起进步⛵这对我很重要~
转载自:https://juejin.cn/post/7103720394770612255