nodejs服务内存泄露排查过程

引言

在开发和部署Node.js应用程序时,内存泄露是一个常见的挑战。本文将探讨如何对于一个陌生项目进行内存排查和优化的方法。

背景

首先项目最初不是自己写的,项目接手一段时间后才发现了问题,往往这种情况不能第一时间定位到具体代码,需要根据用户反馈以及工具排查。

刚开始用户反馈接口卡顿,影响正常使用,我这边查看日志发现没有异常报错,就尝试重启应用,重启后解决问题。

分析问题

我尝试了以下步骤

  1. 由于是代理服务,我以为是请求过多,导致服务日志写入过多导致,所以我只保留了严重错误日志,运行一段时间后发现无效
  2. 由于前不久做过一次容器化部署,程序跑一段时间后会生成 core.42 文件,文件很大,有30G, 该文件是进程崩溃的内存和寄存器的快照。我又尝试不使用 docker 部署,运行一段时间后发现无效
  3. 使用pm2 list 发现进程的内存使用异常高,高达3.4GB,这才发觉可能是内存泄露导致程序崩溃
arduino 复制代码
pm2 list
┌────┬─────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name    │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├────┼─────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0  │ erra    │ default     │ 0.6.53  │ cluster │ 30696    │ 2h     │ 23   │ online    │ 0%       │ 3.4gb    │ root     │ disabled │
└────┴─────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

内存泄漏分析

  1. 利用Node.js内置工具: Node.js提供了一些内置工具来分析内存使用情况,如--inspect参数。启动Node.js应用程序时加上该参数,并使用Chrome开发者工具的Memory选项来观察内存使用情况。
bash 复制代码
node --inspect  --heapsnapshot-signal=SIGUSR2 ./bin/erra.js start
  1. 打开 chrome://inspect/#devices

  2. 启动项目后,先在Menory中创建一个初始的快照

  3. 然后进行多次操作(根据项目流程操作),在创建一个快照进行内存对比,发现内存翻倍的增加

  4. 通过 Retained Size 排序,展开头几项看看,展开到能看到具体对象或者方法为止

    通过展开(closure)也可以定位到文件,到此基本可以确定是 proxy-server.js文 件 与proxyReq 对象相关出现了内存泄露,由于我是本地调试,所以可以通过点击文件名跳转到源码处

解决问题

通过代码发现,确实存在漏洞, 这种情况属于事件监听器未移除 (由于初版代码不是自己写的,不能一眼发现此处有问题。)

虽然这里可以改成监听事件处理后释放就可以解决,但是其实这里只需监听一次就行避免频繁监听并移除

验证结果

为保证是否还存在其他问题,需要重复上面的步骤,重新验证是否还存在内存泄露。经过多次模拟操作之后,内存稳定在 16.6M 左右,确定没问题后在发布

结论

由于代码可以在本地复现,所以排查过程还是比较顺利的。如果是盲排重点从:定时器未清除、事件监听器未移除、未释放资源 方向入手。

相关推荐
田猿笔记1 小时前
在 Node.js 中正确处理 `async/await` 及数组迭代
node.js
Domain-zhuo11 小时前
如何提高webpack的构建速度?
前端·webpack·前端框架·node.js·ecmascript
田猿笔记12 小时前
解决 Node.js 单线程限制的有效方法
node.js
蟾宫曲12 小时前
Node.js 工具:在 Windows 11 中配置 Node.js 的详细步骤
windows·npm·node.js·前端工具
web1350858863514 小时前
前端node.js
前端·node.js·vim
滚雪球~1 天前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语1 天前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
m0_748234521 天前
前端Vue3字体优化三部曲(webFont、font-spider、spa-font-spider-webpack-plugin)
前端·webpack·node.js
丰云1 天前
一个简单封装的的nodejs缓存对象
缓存·node.js
泰伦闲鱼1 天前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs