最上面的虚拟内存大小是什么意思?


124

我正在运行top以监视服务器性能,并且我的2个Java进程显示了高达800MB-1GB的虚拟内存。那是一件坏事?

虚拟内存是什么意思?

哦,顺便说一句,我有1GB的交换空间,它显示已用0%。所以我很困惑。

Java进程= 1个Tomcat服务器+我自己的Java守护程序服务器= Ubuntu 9.10(karmic)


Answers:


142

虚拟内存甚至不一定是内存。例如,如果某个进程使用内存映射一个大文件,则该文件实际上存储在磁盘上,但在该进程中仍会占用“地址空间”。

地址空间(即进程列表中的虚拟内存)不花任何钱;这不是真实的。真正的是RSS(RES)列,它是常驻内存。那就是一个进程占用的实际内存量。

但这还不是全部答案。如果某个进程调用fork(),它将分为两部分,并且它们最初都共享所有RSS。因此,即使RSS最初为1 GB,分叉后的结果也将是两个进程,每个进程的RSS为1 GB,但是您仍然只使用1 GB的内存。

感到困惑了吗?这是您真正需要了解的内容:使用free命令并在启动程序之前和之后检查结果(+/- buffers/cache在线)。区别在于您新启动的程序使用了多少内存。


2
“在启动程序之前和之后检查结果”,或者,使用所返回的USS(唯一设置大小)smem
休伯特·卡里奥

因此,有没有一种工具可以提供所使用的真实内存量,而不是第三方的工具。
CMCDragonkai 2014年

@CMCDragonkai是的,免费。
deviantfan 2015年

1
如果我通过启动Java进程java -Xmx16g RunLong,它将为Java进程保留16Gb内存,那么VIRT最重要的是,似乎已在计入16Gb。在这种情况下,此16Gb内存的类型是什么,即映射的内存还是..?
埃里克·王

1
@EricWang,未映射内存。这只是对OS的请求,以保留以后可能需要的内存(也许永远不需要)。(至少)在Linux上,这是带有MAP_NORESERVE和PROT_NONE标志的mmap调用(请参阅os :: pd_reserve_memory调用anon_mmap:github.com/AdoptOpenJDK/openjdk-jdk11u/blob/…);默认情况下,实际上不分配任何内存-仅在程序确实需要内存才能满足对象分配请求时才进行分配。
20:07

23

在top(1)手册页中:

o: VIRT  --  Virtual Image (kb)
      The  total  amount  of  virtual  memory  used  by the task.  It
      includes all code, data and shared libraries  plus  pages  that
      have been swapped out.

      VIRT = SWAP + RES.

RES表示驻留内存(使用的物理内存)。

实际上,这是不正确的(不再)。当它说“交换”时,它还包括程序已映射到其地址空间的文件,这实际上可能会或可能不会消耗实际的RAM。该内存是文件支持的,但实际上并没有交换。

VIRT还包括已分配但尚未用于任何页面的页面。任何处于这种状态的页面都将映射到内核“零页面”(精巧的概念-您应该查找它),因此它可以在VIRT中显示,但实际上并不消耗任何内存。


2
很有意思,VIRT = SWAP + RES也是如此,我的SWAP使用率为什么为零,而2个Java进程的虚拟内存接近1GB?
卡普索,2010年

交换:总计1048568k,已使用0k,免费1048568k,已缓存
505728k

15
@ user42159这个答案是错误的!男士上装没有'VIRT = SWAP + RES'!-m : VIRT/USED toggle Reports USED (sum of process rss and swap total count) instead of VIRT。可惜我不能拒绝这个答案。
duleshi

3
这个答案是不正确的。USED​​ = Res + Swap Size(从顶部字段管理,在顶部通过按f键访问。也在顶部手册页中访问)。
杰森·S

14

我发现Mugurel Sumanariu的解释很清楚:

VIRT代表进程的虚拟大小,它是实际使用的内存,已映射到自身的内存(例如X服务器的视频卡的RAM),已映射到其中的磁盘上文件的总和。尤其是共享库),以及与其他进程共享的内存。VIRT表示程序当前可以访问多少内存。

RES代表常驻大小,这是一个进程消耗多少实际物理内存的准确表示。(这也直接对应于%MEM列。)这实际上总是小于VIRT大小,因为大多数程序都依赖于C库。

SHR指示实际可共享的VIRT大小(内存或库)。对于库而言,并不一定意味着整个库都位于该库中。例如,如果一个程序仅使用库中的几个函数,则整个库将被映射并在VIRT和SHR中计数,但实际上只有包含所使用函数的库文件部分会被加载并计数根据RES。


我可能只想改写“ VIRT表示程序当前可以访问多少内存”。类似于“ VIRT代表当前程序整个可寻址空间的大小”。好的,那仍然可以使用抛光剂。但是关键是,当VIRT 与RAM空间无关时,“多少内存”仍然可以给我们留下印象。实际上,大型程序通常具有的VIRT大小是系统RAM总大小的几倍-因为VIRT几乎完全是文件支持的地址区域(也称为“磁盘而非RAM”)。
FeRD


2

Linux支持虚拟内存,即使用磁盘作为RAM的扩展,以便可用内存的有效大小相应增加。内核会将当前未使用的内存块的内容写入硬盘,以便将该内存用于其他用途。当再次需要原始内容时,会将它们读回内存。所有这些都对用户完全透明;在Linux下运行的程序只会看到大量可用内存,而不会注意到其中的某些部分会不时地驻留在磁盘上。当然,与使用实际内存相比,读取和写入硬盘的速度要慢(大约慢一千倍),因此程序的运行速度不会那么快。硬盘中用作虚拟内存的部分称为交换空间。

Linux可以将文件系统中的普通文件或单独的分区用于交换空间。交换分区速度更快,但是更改交换文件的大小更容易(无需重新分区整个硬盘,也可以从头开始安装所有内容)。当您知道需要多少交换空间时,就应该使用交换分区,但是如果不确定,可以先使用交换文件,再使用系统一段时间,以便您可以感觉到有多少交换空间有需要时,然后在对分区大小有信心的情况下创建交换分区。

您还应该知道Linux允许一个人同时使用多个交换分区和/或交换文件。这意味着,如果您仅偶尔需要很少数量的交换空间,则可以在这种情况下设置一个额外的交换文件,而不是始终保持分配的总量。

关于操作系统术语的注释:计算机科学通常区分交换(将整个过程写到交换空间中)和分页(一次仅写固定大小的部分,通常一次写几千字节)。分页通常更有效,这就是Linux的工作方式,但是传统的Linux术语仍然谈论交换。

资料来源:http : //www.faqs.org/docs/linux_admin/x1752.html


1
这个答案传播了这样一种误解,即虚拟内存与交换或分页相同。使用磁盘作为RAM的扩展早于虚拟内存。而且有许多系统(例如大多数SoHo路由器)具有虚拟内存,但不使用磁盘作为RAM的扩展。(而且这也不是OP的问题的答案,因为他没有使用任何交换。)
David Schwartz

2

VIRtual顶部的列是指进程的超空间(超级消耗空间),该进程在运行时可能并未实际占用。还有另一列RESident,它指的是运行时进程分配的实际物理内存/空间。

可以通过示例理解两者之间差异的原因:如果进程使用的是某些库,则库的大小也将有助于virtual-size。但是,由于只使用了库的一部分(即正在使用的某些方法),因此对会有所帮助resident-size

查阅更多信息


0

“ VIRT”只是地址空间,RES是“实际”内存,但是“ RES”的“ SHR”(=共享)数量是与其他进程共享的RES的一部分。因此,对于大多数进程来说,我相信通过从RES中减去SHR可以使您真正归属于此特定进程的内存量。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.