我有一个 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%
|