
我有一个 centos 的容器里面运行的是 pm2-docker ,然后 pm2-docker 运行了一个 nodejs 程序,现在时不时会出现系统内存被吃光的问题,看 top 里 node 的内存占用 10%左右, pm2 list 看启动的 nodejs 程序也只有 100M 左右,实际系统已经被吃掉 90%的内存开始出现性能警告了,只要我重启下这个容器,系统内存就降下来正常了,这种情况是什么造成了内存泄露?我写的 nodejs 么?
1 hpeng 2017-03-23 13:48:19 +08:00 via iPhone 一般来说是的,你可以 docker 启动限制容器内存 |
3 xujialiang 2017-03-23 13:57:44 +08:00 那你试试不要用 pm2 docker ,我容器跑 nodejs ,貌似没发生这种问题。 |
4 yuyuyu OP @xujialiang 我试试 , google 过 nodejs 内存相关的东西,都是 top 和 pm2 list 就能看到内存暴涨,但我这里的情况是 top 和 pm2 list 看内存占用都非常正常,比较迷 |
5 unclechan 2017-03-23 15:37:09 +08:00 有可能是 pm2 本身占用内存过多,我以前遇到过 pm2 莫名占用 cpu 很高的问题,不知道是不是 bug |
6 chairuosen 2017-03-23 15:41:28 +08:00 我遇到过 pm2 自己 cpu 太高崩掉的问题,发现是 0.10node 时装的 pm2 跑在 6.几 node 里导致的,更新了 Pm2 就好了 |
7 WildCat 2017-03-23 15:43:29 +08:00 既然用 docker 了,最佳实践应该直接启动 node app 而不是用 pm2 吧? (新手 |
8 WildCat 2017-03-23 15:43:37 +08:00 (我是新手 |
9 otakustay 2017-03-23 15:43:41 +08:00 用 top 看内存正常说明这些内存已经和 node 这个进程无关了,就算用 profile 都查不出来,只能瞎猜了,先去掉 pm2 看看能不能正常,不行再去掉几个功能模块半分法找? |
10 yuyuyu OP @unclechan @chairuosen 我没有去掉 pm2 ,在执行 docker exec web pm2 restart all 以后内存恢复正常……大概还是我的程序有问题吧 @otakustay 我也找不到其他占用内存多的程序……那泄露的内存就完全看不到到哪去了? 我现在试试 heapdump |
11 fyibmsd 2017-03-23 16:30:14 +08:00 docker 里为啥还要用 pm2 |
14 yuyuyu OP 通过 heapdump 收集了内存快照,在内存暴涨的时候, heapdump 出来的快照最多也就 22M ,里面最大的 shallow size 也只有几 M ,引用的包就这些: ``` "dependencies": { "babel-runtime": "6.x.x", "bluebird": "3.3.5", "heapdump": "^0.3.7", "log4js": "^0.6.37", "mysql": "^2.11.1", "sequelize": "^3.23.3" }, ``` 对,用了 babel+bluebird ,然后程序里很多 await |
15 denghongcai 2017-03-23 22:36:55 +08:00 你是不是跑在 docker 里打日志了? docker 版本多少? |
16 yuyuyu OP @denghongcai 确实会打日志 Docker 版本 Docker version 1.13.1, build 092cba3 |
17 yuyuyu OP @denghongcai 我只是直接通过 console.log 输出日志 |
18 mooncakejs 2017-03-23 23:24:28 +08:00 via iPhone echo 1 > /proc/sys/vm/drop_caches 可以释放掉。应该是内存碎片吧 |
19 yuyuyu OP @mooncakejs 试了下内存丝毫没变, 2 、 3 也试过 |
20 mooncakejs 2017-03-23 23:46:37 +08:00 via iPhone @yuyuyu 在宿主机里使用的? |
21 mooncakejs 2017-03-23 23:47:09 +08:00 via iPhone @yuyuyu 我碰到过吃内存的情况。宿主机里可以清掉 |
22 yunshansimon 2017-03-24 00:21:03 +08:00 nodejs 如果创建了独立的子进程,子进程内有 listener 之类的,它不会在完成任务后主动关闭,需要父进程发信号关闭。如果父进程在关闭自己的子进程之前就被关闭了,子进程就变成孤单的进程了,它会自己运行,谁都不属于,被占的内存也不会被释放。因此,必须在创建子进程的父进程内建立子进程列表,在父进程关闭前,向所有子进程发送强制关闭的消息。所以,子进程就跟名字一样,谁生的,谁必须负责到底。 |
23 yuyuyu OP @mooncakejs 嗯,是在宿主机执行的 |
24 yuyuyu OP @yunshansimon 但是我这没有创建任何子进程,整个程序很简单就一个 httpserver ,然后会执行 http.request 去请求数据返回给客户端,就是业务内部的一个 http 中转程序 |
25 denghongcai 2017-03-27 09:53:05 +08:00 Node 进程内存占用不大,但是 Docker 进程占用大吧 把 console.log 改成向文件输出日志,在 Docker 容器了往 stdout 打日志会内存泄露,我时常碰到,但是每次 Docker 那边都没修好 |
26 yuyuyu OP @denghongcai 没有, docker 进程内存也正常,没有哪个进程占用很大的内存,都挺正常的,给我的感觉就是内存消失了……然而只要重启 nodejs 的那个容器内存就回来了,打日志的我也去掉了,问题依旧 |
27 lyzlyz 2018-04-11 10:53:39 +08:00 请问这个问题解决了吗?我跟你遇到了一摸一样的问题,也是 docker 中使用 pm2 运行 nodejs,内存会缓慢的上升直到 100% |