维护服务器时发现:
系统内存几乎被占满,但用 htop / top 看不到任何大进程,所有进程加起来远小于实际占用。
一开始以为是缓存问题,但 free -h 显示缓存量正常,drop_caches 也无法释放内存。
最终排查发现是Docker 残留容器挂载导致的匿名内存泄漏。
关键线索
使用命令:
sudo du -sh /var/lib/docker/overlay2 2>/dev/null显示:
3.2G /var/lib/docker/overlay2说明 Docker 文件系统层占用不少。
执行:
docker system prune -af结果:
Total reclaimed space: 0BDocker 自己认为“没有可清理的对象”,但实际上仍在占用系统内存。
原理简析
每个 Docker 容器会创建:
- 一层文件系统(overlay2);
- 一个共享内存区
/dev/shm; - 若干挂载点和临时文件。
即使容器停止,只要挂载未被卸载,这些区域仍然占用内存。
更糟糕的是:
docker system prune无法识别这些“残挂容器”;- 系统不会自动释放对应的匿名页。
只有在容器挂载被卸载时,内核才会真正回收内存。