CentOS 上 Node.js 内存优化实操指南
一 基础检查与快速止损
- 确认运行环境为 64 位 Node.js(32 位进程地址空间受限,常见上限约 1.5GB)。
- 监控内存趋势:在应用内定期打印 process.memoryUsage(),在系统侧用 top/htop/vmstat 观察 RSS 增长;必要时用 kill -USR2 触发堆快照,或使用 heapdump 模块写快照,再用 Chrome DevTools Memory 面板对比快照定位持续增长对象。
- 临时止血:使用 PM2 设置内存阈值自动重启,例如 pm2 start app.js --max-memory-restart 4G,避免长期膨胀导致 OOM。
- 系统资源兜底:用 free -h 检查可用内存与 Swap,内存紧张时可按需增加 Swap(示例:fallocate/mkswap/swapon),为排查与恢复争取时间。
二 运行时参数与进程架构
- 合理设置堆上限:通过环境变量 NODE_OPTIONS=“–max-old-space-size=4096” 将老生代上限设为 4GB(根据容器/实例内存与业务峰值调优,避免盲目放大)。
- 选择 Node.js LTS 版本并持续更新,获取内存管理与性能修复红利。
- 多核与隔离:使用 cluster 模块或 PM2 集群模式分摊负载,降低单进程内存压力,并提升整体稳定性与吞吐。
- 反向代理与静态资源:用 Nginx 承载静态文件、缓存与 SSL/TLS/HTTP/2,将压缩、连接管理等开销从 Node.js 剥离,间接减少内存占用与 GC 压力。
三 代码与数据模式优化
- 处理大对象/大文件时使用 Streams,避免一次性读入内存;I/O 一律使用异步 API,杜绝 fs.readFileSync 等阻塞调用。
- 控制对象生命周期:避免不必要的 全局变量 与长期存活的 闭包 引用;在组件卸载或请求结束处及时 移除事件监听器、清除定时器。
- 缓存策略:为内存缓存设置 最大容量/TTL 与淘汰策略;对键/值关系不强或需自动回收的场景,优先使用 WeakMap/WeakSet/WeakRef。
- 数据结构与算法:减少临时对象创建,复用对象/缓冲池,选择时间复杂度更优的算法与合适的数据结构。
四 数据库与缓存层优化
- 数据库连接池:复用连接,设置合理的最大连接数与空闲回收,避免频繁建立/销毁连接带来的内存抖动与资源浪费。
- 查询优化:为高频查询字段建立 索引,避免 SELECT *,按需投影;分页/批量操作使用游标或流式处理,减少一次性拉取大量数据。
- 分层缓存:热点数据使用 Redis 或进程内 LRU 缓存,命中率优先;为缓存设置 过期与淘汰策略,防止无限增长。
五 监控 诊断与上线策略
- 观测与告警:在应用内记录 process.memoryUsage() 与关键业务指标;结合 PM2、系统监控与 APM(如 New Relic/Elastic APM)建立内存增长与 GC 异常告警。
- 堆分析与泄漏定位:使用 node --inspect + Chrome DevTools Memory 做快照对比;生产可用 heapdump 响应 SIGUSR2 写快照;也可用 memwatch-next 监听泄漏事件。
- 上线与压测:在类生产环境复现实例规格与流量,结合 ab/siege 压测观察 RSS、GC 与延迟曲线,先修复泄漏再谈容量规划。
- 兜底与扩缩:为突发流量配置 PM2 --max-memory-restart;必要时水平扩展实例数,配合 Nginx 负载均衡与健康检查。