VIRT是进程可访问的虚拟地址空间总和,包含已映射但未使用的堆栈页、mmap文件(如共享库)、换出到swap的内存及预留地址空间,不反映实际物理内存占用。

什么是 VIRT,它到底包含哪些内存?
VIRT 是 top、ps 等工具中表示“虚拟内存大小”的字段,单位通常是 KB。它不是进程当前实际占用的物理内存,而是该进程**地址空间中所有可访问内存页的总和**,包括:
-
mmap映射的文件(如动态库、共享内存、内存映射文件) - 已分配但尚未写入的堆内存(
malloc后未 touch 的页) - 已换出到 swap 的内存页
- 未实际使用的栈预留空间(stack guard pages 也算在内)
所以 VIRT 值偏大很常见——一个只用了 10MB 物理内存的 Java 进程,VIRT 可能显示 4GB,因为 JVM 预留了整个堆地址空间。
为什么不能用 VIRT 判断内存压力?
系统是否缺内存,看的是真实物理内存(RES)和可用内存(free + buffers + cached),不是 VIRT。常见误判场景:
- 启动一个
qemu虚拟机,VIRT瞬间飙升几十 GB,但RES可能只有几百 MB —— 这是正常预留,不占物理资源 -
glibc的malloc在小块分配时用brk,大块用mmap;后者会直接计入VIRT,但未必立刻增加RES -
VIRT包含共享库(如libc.so.6),多个进程共用同一段物理内存,但各自VIRT都算一遍 —— 会造成重复统计
换句话说:VIRT 是“进程能看见多少内存”,不是“它正在用多少内存”。
怎么查进程真实的内存开销?优先看 RES 和 %MEM
判断一个进程吃不吃内存,盯住这两个字段更可靠:
-
RES(Resident Set Size):当前真正驻留在物理内存中的字节数,不含 swap,也不含未映射页 -
%MEM:该进程RES占系统总物理内存(MemTotal)的百分比
实操建议:
- 按内存排序找大户:
ps aux --sort -rss | head -n 10 - 动态观察单个进程:
top -p <code>PID,然后按Shift+M确保按RES排序 - 确认
RES是否异常增长:watch -n 1 'cat /proc/<code>PID/statm',第二列即为RES(单位 page)
注意:RES 仍含共享内存(SHR),若想排除共享部分看独占内存,需用 smaps 分析:awk '/^Rss:/ {sum+=$2} END {print sum}' /proc/<code>PID/smaps。
VIRT 异常高但 RES 正常,要不要干预?
多数情况下不用。除非你观察到以下组合现象:
-
VIRT持续线性增长(比如每小时涨 1GB),且RES同步上涨 -
free显示available趋近于 0,同时swap使用量明显上升(free -h第三行SwapUsed) - 系统开始频繁
OOM kill进程(dmesg | grep -i "killed process")
此时才需要深入查:是不是 mmap 泄漏?是否 madvise(MADV_DONTNEED) 没调用?或者程序本身存在地址空间碎片化问题。单纯 VIRT 数值大,只是 Linux 内存管理机制的常态表现,不是故障信号。


















