为何Docker显示的内存占用与实际不符?容器内存异常排查
Docker容器内存持续增长排查方案
一、先解决docker stats与容器内进程内存统计不一致的问题
两者统计维度不同,导致数据差异:
docker stats统计的是容器的总内存占用,包含应用进程、容器初始化进程(PID 1)、日志缓冲区、共享库、内核页面缓存等所有容器内资源的内存开销- htop显示的是单个进程的内存使用,需要注意区分
VIRT(虚拟内存,包含未实际分配的空间)和RES(实际物理内存占用),若应用是多进程架构,需将所有进程的RES值求和后再与docker stats对比
验证真实内存占用的方法:
- 进入容器执行
ps aux --sort=-%mem,统计所有进程的RSS列总和 - 执行
docker inspect <容器ID>,查看MemoryStats字段:usage为容器总内存,stats.total_rss为所有进程物理内存总和,这两个值能准确反映真实内存使用情况
二、排查Rust + Axum应用的潜在内存泄漏
即使本地测试无异常,容器环境的资源限制、异步任务调度差异可能触发泄漏:
- 开启内存 profiling:
- 用
tracing搭配tokio-console监控异步任务生命周期,检查是否有未取消的后台任务 - 使用
heaptrack对容器内进程做堆内存分析(需容器开启--privileged或挂载调试工具)
- 用
- 检查常见泄漏点:
- 是否存在
Arc循环引用导致内存无法释放 - 全局静态变量(如自定义缓存)是否持续累积数据未设置过期策略
- Axum路由中的状态管理是否有未正确释放的资源(如数据库连接池未配置最大连接数)
- 是否存在
三、排查Docker层面的内存增长因素
- 日志驱动问题:若使用
json-file驱动且未配置日志滚动,日志缓冲区会持续占用内存,可通过docker logs --tail 100 <容器ID>查看日志量,配置max-size和max-file参数限制日志大小 - 临时文件与缓存:检查容器内
/tmp目录是否有未清理的大文件,若挂载了tmpfs(内存文件系统),这些文件会直接占用内存 - 内存限制与内核回收:若未设置容器内存限制,内核页面缓存可能未及时回收,可尝试设置
--memory限制并观察内存增长趋势
四、验证与复现
- 将容器内的应用运行环境迁移到本地,用
ulimit -v或systemd-run模拟容器的内存限制,复现是否出现内存增长 - 更换轻量基础镜像(如
rust:alpine),减少基础镜像带来的额外内存开销,对比内存变化
内容的提问来源于stack exchange,提问作者mohammad javad
相关产品推荐
相关产品推荐

