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

结论

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

相关推荐
理想不理想v6 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
暮毅10 小时前
10.Node.js连接MongoDb
数据库·mongodb·node.js
~甲壳虫16 小时前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
~甲壳虫17 小时前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js
~甲壳虫17 小时前
说说webpack proxy工作原理?为什么能解决跨域
前端·webpack·node.js
熊的猫17 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
前端青山1 天前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
GDAL1 天前
npm入门教程1:npm简介
前端·npm·node.js
郑小憨2 天前
Node.js简介以及安装部署 (基础介绍 一)
java·javascript·node.js
lin-lins2 天前
模块化开发 & webpack
前端·webpack·node.js