Nodejs+docker 内存泄露问题
Nodejs+docker 内存泄露问题
我有一个 centos 的容器里面运行的是 pm2-docker ,然后 pm2-docker 运行了一个 nodejs 程序,现在时不时会出现系统内存被吃光的问题,看 top 里 node 的内存占用 10%左右, pm2 list 看启动的 nodejs 程序也只有 100M 左右,实际系统已经被吃掉 90%的内存开始出现性能警告了,只要我重启下这个容器,系统内存就降下来正常了,这种情况是什么造成了内存泄露?我写的 nodejs 么?
一般来说是的,你可以 docker 启动限制容器内存
我是想找出内存泄露,限制内存重启容器都不是解决方法……
那你试试不要用 pm2 docker ,我容器跑 nodejs ,貌似没发生这种问题。
我试试 , google 过 nodejs 内存相关的东西,都是 top 和 pm2 list 就能看到内存暴涨,但我这里的情况是 top 和 pm2 list 看内存占用都非常正常,比较迷
有可能是 pm2 本身占用内存过多,我以前遇到过 pm2 莫名占用 cpu 很高的问题,不知道是不是 bug
我遇到过 pm2 自己 cpu 太高崩掉的问题,发现是 0.10node 时装的 pm2 跑在 6.几 node 里导致的,更新了 Pm2 就好了
(我是新手
用 top 看内存正常说明这些内存已经和 node 这个进程无关了,就算用 profile 都查不出来,只能瞎猜了,先去掉 pm2 看看能不能正常,不行再去掉几个功能模块半分法找?
我没有去掉 pm2 ,在执行 docker exec web pm2 restart all 以后内存恢复正常……大概还是我的程序有问题吧
我也找不到其他占用内存多的程序……那泄露的内存就完全看不到到哪去了?
我现在试试 heapdump
docker 里为啥还要用 pm2
pm2 深入进程的监控能提供很多操作系统层面拿不到的信息
能详细说说么
通过 heapdump 收集了内存快照,在内存暴涨的时候, heapdump 出来的快照最多也就 22M ,里面最大的 shallow size 也只有几 M ,引用的包就这些:<br>"dependencies": {<br> "babel-runtime": "6.x.x",<br> "bluebird": "3.3.5",<br> "heapdump": "^0.3.7",<br> "log4js": "^0.6.37",<br> "mysql": "^2.11.1",<br> "sequelize": "^3.23.3"<br> },<br>
对,用了 babel+bluebird ,然后程序里很多 await
你是不是跑在 docker 里打日志了? docker 版本多少?
确实会打日志 Docker 版本 Docker version 1.13.1, build 092cba3
我只是直接通过 console.log 输出日志
echo 1 > /proc/sys/vm/drop_caches 可以释放掉。应该是内存碎片吧
试了下内存丝毫没变, 2 、 3 也试过
在宿主机里使用的?
我碰到过吃内存的情况。宿主机里可以清掉
nodejs 如果创建了独立的子进程,子进程内有 listener 之类的,它不会在完成任务后主动关闭,需要父进程发信号关闭。如果父进程在关闭自己的子进程之前就被关闭了,子进程就变成孤单的进程了,它会自己运行,谁都不属于,被占的内存也不会被释放。因此,必须在创建子进程的父进程内建立子进程列表,在父进程关闭前,向所有子进程发送强制关闭的消息。所以,子进程就跟名字一样,谁生的,谁必须负责到底。
嗯,是在宿主机执行的
但是我这没有创建任何子进程,整个程序很简单就一个 httpserver ,然后会执行 http.request 去请求数据返回给客户端,就是业务内部的一个 http 中转程序
Node 进程内存占用不大,但是 Docker 进程占用大吧
把 console.log 改成向文件输出日志,在 Docker 容器了往 stdout 打日志会内存泄露,我时常碰到,但是每次 Docker 那边都没修好
没有, docker 进程内存也正常,没有哪个进程占用很大的内存,都挺正常的,给我的感觉就是内存消失了……然而只要重启 nodejs 的那个容器内存就回来了,打日志的我也去掉了,问题依旧
请问这个问题解决了吗?我跟你遇到了一摸一样的问题,也是 docker 中使用 pm2 运行 nodejs,内存会缓慢的上升直到 100%
针对Node.js在Docker环境中可能遇到的内存泄露问题,以下是一些排查和解决建议:
-
监控内存使用: 使用Docker的stats命令监控容器内存使用情况:
docker stats [CONTAINER_ID]
结合Node.js应用中的内存监控工具,如
process.memoryUsage()
,持续观察内存变化趋势。 -
代码审查: 检查代码中是否存在未释放的资源,如全局变量、事件监听器未解绑等。使用工具如ESLint检测潜在问题。
-
垃圾回收调优: Node.js默认垃圾回收机制已足够高效,但在某些极端情况下,可以尝试调整
--max-old-space-size
参数增加堆内存限制:node --max-old-space-size=4096 app.js
-
Docker资源限制: 在Docker运行配置中设置内存限制,防止单个容器消耗过多资源:
docker run -m 512m node_app
-
内存泄漏检测工具: 使用Node.js的内存泄漏检测工具,如
heapdump
和Chrome DevTools
的Heap Snapshot功能,分析内存快照找出泄漏点。 -
定期重启容器: 作为临时措施,可以设置Docker容器自动重启策略,以缓解内存泄漏导致的服务不稳定问题。
通过上述方法,可以有效定位和解决Node.js在Docker环境下的内存泄露问题。如果问题依然存在,建议深入分析应用逻辑,必要时重构代码。