问题描述
我在 Docker 容器上看到我的进程的 RAM 占用,但它似乎产生了泄漏。
我做了以下步骤:
- 在不运行任何东西的情况下创建 docker 并使用正确的结果执行
docker stats [CONTAINER_ID]
:
CONTAINER ID NAME cpu % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
0ac5cdb9d61b unruffled_margulis 0.00% 852KiB / 12.69GiB 0.01% 736B / 0B 0B / 0B 1
- 然后我启动了一个进程,该进程等待队列中的输入(但在侦听期间我不会发送任何输入来检查其占用情况)。该进程分配资源,因为它加载了一些模型:
root@d6d1d82fe4c7:/app# listen.py
以及这些统计数据:
CONTAINER ID NAME cpu % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
0ac5cdb9d61b unruffled_margulis 0.00% 4.628GiB / 12.69GiB 36.49% 8.2kB / 2.61kB 0B / 0B 11
- 然后我停止进程并以同样的方式重新启动它:
root@d6d1d82fe4c7:/app# ^C
root@d6d1d82fe4c7:/app# listen.py
CONTAINER ID NAME cpu % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
0ac5cdb9d61b unruffled_margulis 0.00% 8.451GiB / 12.69GiB 66.62% 15.8kB / 5.54kB 0B / 0B 11
难以置信的内存占用是之前的两倍!!!进程被杀掉了,但就好像之前进程的模型还在Docker中加载一样。
- 再次杀死进程后,没有重新启动它:
root@d6d1d82fe4c7:/app# ^C
CONTAINER ID NAME cpu % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
0ac5cdb9d61b unruffled_margulis 0.00% 3.825GiB / 12.69GiB 30.15% 16.3kB / 5.86kB 0B / 0B 1
在没有任何进程运行的情况下分配了一些资源。使用 htop
,我看到了不同的 RAM 使用量:800MiB,这对于无所事事来说太多了,并且与 docker stats
不同。
我试图重复这一点,似乎在 2 次启动后,RAM 块在 8GiB 上(在其他尝试中也没有超过),但这种行为正常吗?如何清理 Docker 上的 RAM?
编辑
经过一些实验,我尝试将最大 Docker 内存限制为 7GB,以便在“第一次增加 RAM”后看到容器 killed
。但是使用这种新配置,RAM 稳定在 4.628GiB。
再次将限制设为 13GB,第二次运行时 RAM 恢复到 8.451GiB。奇怪的是,在这个增量之后,在接下来的步骤中似乎不会再次增加。而如果我加载更少的模型,为了分配更少的内存,似乎每次启动脚本都会增加内存。
所以我的直觉是 Docker 缓存了一些资源,但是如果达到内存限制,它会释放缓存并分配新资源。
使用我在开头看到的命令 free -m
:
root@29d5547ba8ec:/app# free -m
total used free shared buff/cache available
Mem: 12989 412 11638 400 938 11876
Swap: 1023 0 1023
在第一次发布之后:
root@29d5547ba8ec:/app# free -m
total used free shared buff/cache available
Mem: 12989 454 7477 400 5057 11841
Swap: 1023 0 1023
请参阅字段 buff/cache
。不知道对不对?
解决方法
要释放容器上的内存,您可以:
- 重启docker容器
- 清除主机服务器内存
这是因为 Docker 容器被表示为主机系统上的进程。因此,您需要释放与容器进程关联的内存。这可能很困难,尤其是因为进程可能依赖于共享内存结构。
如果你想释放内存可以使用以下命令尝试清除主机服务器的内存,如果你使用的是Linux:
刷新磁盘内存缓冲区中的数据:$ sync
仅清除 PageCache。
同步;回声 1 > /proc/sys/vm/drop_caches
清除 dentry 和 inode。
同步;回声 2 > /proc/sys/vm/drop_caches
清除 PageCache、dentries 和 inode。