参考
- nodejs内存泄漏分析工具heapdump
- https://blog.csdn.net/c11073138/article/details/84700482
- nestjs 官方
- nodejs 内存分析
背景
近期新项目,同事使用了 nextjs 作为 web 框架,实现用户会话的建立和维护。上线后,发现内存不断增长,需要排查原因
技术栈
- node 10
- nest js
- redis/ azure redis cache
- 压测工具 hey
- 内存导出工具 heapdump
排查功能
### hey 压测
hey -z 120s -c 4 -cpus 2 -m POST -H "sbux-authorization: Bearer gnadIIBnrIDBY5fH89GG0vsmMm8LVW2Y.igr9LgC8G2AKrul6EY/N+682EIL2QsVe5cPUqVhR6oI" http://127.0.0.1:8000/api/v1/session
hey -z 10s -c 3 http://127.0.0.1:8000/api/v1/user/ping
hey -z 2s -c 4 -cpus 2 -m POST -H "Accept: application/json;Content-Type: application/json" -d 'code=f63262949c48affa86c5cfb9ba7d13f5&grant_type=oauth' http://127.0.0.1:8000/api/v1/user/token
## redis 值检索
docker exec 5f64399a223a redis-cli info
使用 heapdump 生成内存文件,并使用 Chrome memor/ profile 进行分析
Summary 总览视图:按构造函数分组。用于捕捉对象及其使用的内存。对于定位DOM内存泄露特别有用。
Comparison 对比视图:对比两个快照。用于对比不同操作之后的堆快照,查看内存的释放及引用计数,来分析内存是否泄露及其原因。
Containment 内容视图:查看堆内容。更适合查看对象结构,有助于分析对象的引用情况。适用于分析闭包以及深入分析对象。
Statistics 统计视图:总览堆的统计信息。
## Summary 总览视图
Constructor:构造函数,节点下的对象都是由改构造函数创建而来。
Distance:与根节点的距离。
Objects Count:对象个数及百分占比。
Shallow size:对象的直接内存总数,直接内存是指对象自身占用的内存大小。
Retained size:对象的最大保留内存,保留内存是指对象被删除后可以释放的那部分内存。
点击展开构造函数,可以看到所有构造函数相关的对象实例,@后面的数字是该对象实例的唯一标识符。
常见的顶层构造函数:
(global property):全局对象和普通对象的中间对象,和常规思路不同。比如在Window上定义了一个Person对象,那么他们之间的关系就是[global] => (global property) => Person。之所以使用中间对象,是出于性能的考虑。
(closure):使用函数闭包的对象。
(array, string, number, regexp):一系列对象类型,其属性指向Array/String/Number/Regexp。
HTMLDivElement/HTMLAnchorElement/DocumentFragment:元素的引用或者代码引用的指定文档对象。
### 3.1.2 Comparasion对比视图
为了验证特定操作会不会引起内存泄露,对比快照的步骤如下:
1、无任何操作,拍第一个堆快照
2、执行你觉得可能造成内存泄露的操作,再执行相反操作
3、拍第二个堆快照,切换到对照视图,并且指定与第一个堆快照对比
比如你觉得登陆页面内存泄露,那可以先登陆到首页,拍第一个堆快照。然后退出到登陆界面,再重新登陆到首页,录制第二个快照。比对这两个快照的大小,如果增长有可能是泄露,可以反复操作几次。记得每次录制之前要先点击垃圾回收。