位置:首页 > JavaScript > Node.js 在 CentOS 上的内存如何管理

Node.js 在 CentOS 上的内存如何管理

时间:2026-08-24  |  作者:夜鞌不睡  |  阅读:0

目录

  1. 先看清 Node.js 在 CentOS 上到底用的是什么内存
  2. CentOS 系统层面,先把监控和内核参数调到可判断状态
  3. 回到 Node.js 进程本身,重点处理堆上限、泄漏点和数据处理方式
  4. 内存还在涨时,用这些工具把问题定位到对象和代码层
  5. 实操时怎么判断该先调系统还是先查代码

前言

Node.js 服务在 CentOS 上跑久后内存上涨并 OOM,不一定只是“堆太小”。处理时要同时看 V8 内存结构、CentOS 的 Swap 与内核参数,以及代码里的常见泄漏点和排查工具,先分清该扩容、调参,还是抓快照定位。

Node.js 服务在 CentOS 上内存持续上涨并最终 OOM,通常要同时看 V8、CentOS 内存策略和应用代码。先分清是堆、rss 还是 external 在涨,再决定扩堆、调 Swap,还是直接查泄漏。

先看清 Node.js 在 CentOS 上到底用的是什么内存

排查时先区分 3 类内存:

Node.js 与 CentOS 内存结构关系图,展示堆内存、栈内存、原生内存以及新生代和老生代的分工
Node.js 内存结构速览把 V8 堆分代、Node.js 内存类型和排查关注点放在一张图里,方便先判断问题出现在哪一层。
  • 堆内存:JavaScript 对象、闭包,最常见上涨点。
  • 栈内存:基本类型、调用信息,生命周期通常较短。
  • 原生内存:C++ 层使用,如 Buffer,不等同于 V8 堆。

V8 堆又分为:

  • 新生代:短生命周期对象,使用 Scavenge。
  • 老生代:长生命周期或晋升对象,通常由 Mark-Sweep、Mark-Compact 处理。

因此内存一直涨时,先判断增长发生在堆内,还是 rss 这类更大的常驻内存范围。

CentOS 系统层面,先把监控和内核参数调到可判断状态

先确认物理内存、Swap 和进程占用

  • free -h:看物理内存和 Swap 总量、已用量。
  • tophtop:按 %MEM 找高占用进程。
  • vmstat 1:持续观察虚拟内存和系统活动。
  • /proc/meminfo:查看更细项。

先判断是 Node.js 进程失控,还是系统已频繁使用 Swap。

CentOS 系统内存调优关系图,展示监控命令、Swap、swappiness 和 overcommit 的作用范围
CentOS 内存调优重点这一节更适合做成系统侧关系图:先监控,再根据机器内存和业务延迟要求调整 Swap 与内核策略。

按机器情况调整 Swap

物理内存充足且业务对延迟敏感时,可减少甚至关闭 Swap;内存经常不够时,应补充 Swap。示例:创建 2GB 交换文件。

Node.js 内存排查路径图,展示从 process.memoryUsage 到 DevTools、heapdump 和 memwatch-next 的定位步骤
内存泄漏排查路径当内存持续上涨时,先分清增长指标,再决定是抓堆快照、留现场,还是做运行期预警。
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab  # 永久生效

把 swappiness 调低,减少主动换出

vm.swappiness 默认值是 30。对 Node.js 常驻服务,可按机器情况调低到 10:

sudo sysctl vm.swappiness=10
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf  # 永久生效

必要时限制过度分配

vm.overcommit_memory

  • 0:默认策略
  • 1:总是允许
  • 2:严格限制

担心单进程申请过多内存时,可考虑设为 2,更早暴露问题。

回到 Node.js 进程本身,重点处理堆上限、泄漏点和数据处理方式

按业务需要调整堆内存上限

V8 在 64 位系统上的默认堆上限大约是 1.4GB,可用 --max-old-space-size 调整,单位 MB:

node --max-old-space-size=2048 app.js  # 设置为2GB

PM2 可设置内存阈值自动重启:

module.exports = {
  apps: [{
    name: 'app',
    script: 'app.js',
    max_memory_restart: '2G'  // 内存超过2GB时自动重启
  }]
};

调大上限只是增加缓冲,不等于解决泄漏。

优先排查几类高发内存泄漏

  • 全局变量:如忘记写 var / let / const,或挂到 global
  • 未清理的定时器和监听器setIntervalsetTimeoutEventEmitter
  • 闭包长期持有大对象
  • 外部资源未释放:如 fs.closedb.connection.end

大文件和大结果集尽量改成流式处理

const fs = require('fs');
const readStream = fs.createReadStream('large-file.txt');
const writeStream = fs.createWriteStream('output.txt');
readStream.pipe(writeStream);  // 流式传输,减少内存占用

缓存要限额,能外置就外置

进程内缓存要限制大小;多实例或数据量较大时,更适合 Redis、Memcached 这类进程外缓存,避免多个 Node.js 进程各自堆积副本。

内存还在涨时,用这些工具把问题定位到对象和代码层

先用 process.memoryUsage() 看增长发生在哪

  • rss:常驻内存
  • heapTotal:堆总内存
  • heapUsed:堆已用内存
  • external:原生内存
setInterval(() => {
  console.log(process.memoryUsage());
}, 5000);

用 Chrome DevTools 分析堆快照

使用 --inspect 启动后,在 Chrome 打开 chrome://inspect,到 Memory 面板对比多个时间点的堆快照,找出持续存活对象和未断开的引用链。

用 heapdump 导出现场

const heapdump = require('heapdump');
heapdump.writeSnapshot('/tmp/heapdump.heapsnapshot', (err, filename) => {
  console.log('堆快照已保存到', filename);
});

用 memwatch-next 监控异常趋势

const memwatch = require('memwatch-next');
memwatch.on('leak', (info) => {
  console.log('内存泄漏检测到:', info);
});

实操时怎么判断该先调系统还是先查代码

  1. 先用 free -htopvmstat 1 确认是否系统整体内存紧张。
  2. 再看 process.memoryUsage(),判断增长集中在 heapUsedrss 还是 external
  3. 如果只是业务峰值触顶,可调整 --max-old-space-size 或 PM2 的 max_memory_restart
  4. 如果内存长期单向上涨,优先检查全局变量、监听器、闭包、连接和缓存。
  5. 仍无法定位,再用 DevTools、heapdumpmemwatch-next 做对象级分析。

有效治理通常要同时做到:系统参数有边界、进程配置有上限、代码对象能释放、问题现场能留证。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多