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 左右,确定没问题后在发布

结论

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

相关推荐
甜瓜看代码3 小时前
1.
react.js·node.js·angular.js
伍哥的传说3 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
01传说5 小时前
vue3 配置安装 pnpm 报错 已解决
java·前端·vue.js·前端框架·npm·node.js
摘星小杨8 小时前
如何卸载本机的node.js
node.js
Q_Q51100828517 小时前
python的保险业务管理与数据分析系统
开发语言·spring boot·python·django·flask·node.js·php
摘星小杨1 天前
安装nvm管理node.js,详细安装使用教程和详细命令
node.js·nvm
灋✘逞_兇1 天前
Node.Js是什么?
服务器·javascript·node.js
归于尽2 天前
回调函数在Node.js中是怎么执行的?
前端·javascript·node.js
GDAL2 天前
多字节字符的字节被拆分到不同 chunk 中,导致解码失败
node.js
Jacob02342 天前
“Node.js 不行了”?性能争议中的误解与选择真相
后端·node.js