如何检测node中是否存在内存泄露的隐患

2020-07-17 12:31:29 浏览数 (1)

虽然是在节假日期间,但是果然自己还是闲不住,不折腾点东西感觉生活就失去了趣味,闲话不多说,直接开始这次的记录和分享吧。

序言


我想几乎所有的语言都会存在内存泄漏的情况,而 node 也不例外,即使其 v8 引擎拥有优秀的内存管理,内存泄漏其实就是不合理的使用导致内存空间的不够用,比如无限制地使用内存填充数据或着消费内存的速度快于内存清理的速度。一旦我们的服务器存在内存泄漏的风险,其后果将是不堪设想的,所以我们必须重视内存泄露的问题,及时的检测程序中是否存在内存泄漏的隐患十分有必要。

devtool


检测内存泄漏的工具有很多,memwatch、heapdump 这两款非常有名,但是我今天打算推荐另一款工具,没错,就是 devtool 。

安装:

npm install devtool -g

安装过程中你应该会碰到 electron 安装失败的问题(因为源在墙外),解决方式如下:

先找到并删除 node_modules 中的 electron 整个文件夹,然后输入指令替换源重新安装如下:

ELECTRON_MIRROR="https://npm.taobao.org/mirrors/electron/" npm install electron -g

实战


先准备一段存在内存泄漏的代码,文件为 memoryleak.js:

以上代码为什么会存在内存泄漏?因为每次 http 请求进来都会调用 leak 方法往数组 leakArray 中添加数据造成其一直存在于内存中得不到释放。

好吧,运用 devtool 开始检测。

命令行输入:

devtool memoryleak.js --watch

没错,你会看到弹出来了一个窗口:

如上图所示,选择 Profiles 下的第二项 Take Heap Snapshot 抓取内存快照,点击 Take Snapshot 开始抓取,然后你会生成如下界面:

上图就是内存相关的数据,先不着急,我们多发起几次 http 请求(浏览器中多刷新几次 127.0.0.1:3000 就行了),然后再次抓取内存快照:

点击上图红色圈中的小圆点就是抓取内存快照。

此时你看到的界面应该类似如下:

没错,我们得到了两张内存情况的数据,有没有发现图中左边的数据,一个是 6.3M,另一个是 8.8M,你没猜错,这就是内存使用的大小,我们多发起几次请求然后抓取快照如下图:

嗯,6.3M,8.8M,11.9M,13.4M,内存使用大小不断增加,如果出现了这种情况,当然是存在内存泄漏风险的,写到这里,内存泄漏已经被检测存在了,但是本文并没有完,因为我们并不知道具体是哪里存在内存泄漏。

当然,上面抓取了那么多的内存快照数据,通过比对自然就会有所发现。

点击 Summary 旁边的 All objects,选择查看两次内存快照抓取的时间之中发生了:

仔细查看数据,你会发现前几项的 size 并不是 0%,我们点击一项看看具体的情况如下图:

到这里了,你应该发现这一堆的数据是不是已经知道内存泄漏的源头了,再看看上图中的黄色的标记,其实这就是内存一直被占用的意思。

好吧,内存泄漏的源头也发现了,嗯,本文还是不打算结束。

Timeline


再看看 Timeline 吧。

选择 Profiles 左边的 Timeline,然后还是点击左上角的小圆点,将会以时间轴的方式展现数据趋势,如下图:

上图代表正在连续的记录数据中,我们跟前面一样不断地发起请求,然后点击 stop 停止记录,其就会自动生成数据趋势图,如下:

看到上图中蓝色的阶梯形的线没,一旦出现这种形状,也代表这你的程序是存在内存泄漏风险的。

最后


其实,devtool 除了检测内存泄漏之外,还有非常非常多的其它功能可以方便我们进行 node 的开发,当然其它的功能有待大家自己发掘了,就这样吧,最后祝大家清明节快乐!

0 人点赞