我正在运行top
以监控我的服务器性能,其中 2 个 Java 进程显示虚拟内存高达 800MB-1GB。这是件坏事吗?
虚拟内存是什么意思?
顺便说一句,我有 1GB 的交换空间,但显示使用率为 0%。所以我很困惑。
Java 进程 = 1 个 Tomcat 服务器 + 我自己的 java 守护进程服务器 = Ubuntu 9.10 (karmic)
答案1
虚拟内存甚至不一定是内存。例如,如果一个进程将一个大文件映射到内存中,则该文件实际上存储在磁盘上,但它仍占用进程中的“地址空间”。
地址空间(即进程列表中的虚拟内存)不占用任何空间;它不是真实的。真实的是 RSS(RES)列,即常驻内存。这就是进程占用的实际内存量。
但即使这样也不是全部答案。如果一个进程调用 fork(),它会分成两个部分,并且它们最初共享所有 RSS。因此,即使 RSS 最初为 1 GB,分叉后的结果将是两个进程,每个进程的 RSS 为 1 GB,但您仍然只会使用 1 GB 内存。
感到困惑了吗?以下是你真正需要知道的:使用命令free
并在启动程序之前和之后检查结果(在线+/- buffers/cache
)。这个差异是多少新的新启动的程序所使用的内存。
答案2
我找到了这个Mugurel Sumanariu 的解释非常清楚:
VIRT
代表进程的虚拟大小,即进程实际使用的内存、已映射到自身的内存(例如 X 服务器的视频卡 RAM)、已映射到其中的磁盘文件(最明显的是共享库)以及与其他进程共享的内存的总和。VIRT 表示程序当前能够访问的内存量。
RES
代表常驻大小,它精确地表示了进程实际消耗的物理内存量。(这也直接对应于 %MEM 列。)这实际上总是小于 VIRT 大小,因为大多数程序都依赖于 C 库。
SHR
表示 VIRT 大小中有多少是实际可共享的(内存或库)。对于库,这并不一定意味着整个库都是常驻的。例如,如果某个程序只使用库中的几个函数,则整个库都会被映射并计入 VIRT 和 SHR,但只有包含正在使用的函数的库文件部分才会实际加载并计入 RES。
答案3
来自top(1) 手册页:
o:VIRT——虚拟映像(kb)
任务使用的虚拟内存总量。它包括所有代码、数据和共享库以及已换出的页面和已映射但未使用的页面。
请参阅“概述、Linux 内存类型”以了解更多详细信息。
(文档的早期版本指出“VIRT = SWAP + RES”。其中 RES 表示 RESident,或物理已使用的內存。
实际上这已经不正确了(不再正确)。当它说“交换”时,它还包括程序已映射到其地址空间的文件,这些文件可能实际上正在消耗实际 RAM,也可能尚未消耗实际 RAM。此内存是文件支持的,但实际上不是交换。
VIRT 还包括已分配但尚未使用的页面。处于此状态的任何页面都映射到内核零页(绝妙的概念 - 您应该查阅一下),因此它会显示在 VIRT 中,但实际上不会占用任何内存。
答案4
VIRtual
最上面的一列,表示进程的超级空间(超级消耗空间),进程在运行时可能并没有真正占用这些空间。还有一列RESident
,表示进程在运行时实际分配的物理内存/空间。
我们可以通过以下示例来理解两者之间存在差异的原因:如果过程正在使用某个库,那么库的大小也会有助于virtual-size
。但是,由于仅会使用库的一部分(即正在使用的某些方法),因此这将有助于resident-size
。
参考更多信息