Answers:
虚拟内存甚至不一定是内存。例如,如果某个进程使用内存映射一个大文件,则该文件实际上存储在磁盘上,但在该进程中仍会占用“地址空间”。
地址空间(即进程列表中的虚拟内存)不花任何钱;这不是真实的。真正的是RSS(RES)列,它是常驻内存。那就是一个进程占用的实际内存量。
但这还不是全部答案。如果某个进程调用fork(),它将分为两部分,并且它们最初都共享所有RSS。因此,即使RSS最初为1 GB,分叉后的结果也将是两个进程,每个进程的RSS为1 GB,但是您仍然只使用1 GB的内存。
感到困惑了吗?这是您真正需要了解的内容:使用free
命令并在启动程序之前和之后检查结果(+/- buffers/cache
在线)。区别在于您新启动的程序使用了多少新内存。
smem
。
java -Xmx16g RunLong
,它将为Java进程保留16Gb内存,那么VIRT
最重要的是,似乎已在计入16Gb。在这种情况下,此16Gb内存的类型是什么,即映射的内存还是..?
在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中显示,但实际上并不消耗任何内存。
-m : VIRT/USED toggle Reports USED (sum of process rss and swap total count) instead of VIRT
。可惜我不能拒绝这个答案。
我发现Mugurel Sumanariu的解释很清楚:
VIRT
代表进程的虚拟大小,它是实际使用的内存,已映射到自身的内存(例如X服务器的视频卡的RAM),已映射到其中的磁盘上文件的总和。尤其是共享库),以及与其他进程共享的内存。VIRT表示程序当前可以访问多少内存。
RES
代表常驻大小,这是一个进程消耗多少实际物理内存的准确表示。(这也直接对应于%MEM列。)这实际上总是小于VIRT大小,因为大多数程序都依赖于C库。
SHR
指示实际可共享的VIRT大小(内存或库)。对于库而言,并不一定意味着整个库都位于该库中。例如,如果一个程序仅使用库中的几个函数,则整个库将被映射并在VIRT和SHR中计数,但实际上只有包含所使用函数的库文件部分会被加载并计数根据RES。
ps / top输出中的VIRT列与测量内存使用情况几乎无关。不用担心 Apache重载VIRT与RES内存
Linux支持虚拟内存,即使用磁盘作为RAM的扩展,以便可用内存的有效大小相应增加。内核会将当前未使用的内存块的内容写入硬盘,以便将该内存用于其他用途。当再次需要原始内容时,会将它们读回内存。所有这些都对用户完全透明;在Linux下运行的程序只会看到大量可用内存,而不会注意到其中的某些部分会不时地驻留在磁盘上。当然,与使用实际内存相比,读取和写入硬盘的速度要慢(大约慢一千倍),因此程序的运行速度不会那么快。硬盘中用作虚拟内存的部分称为交换空间。
Linux可以将文件系统中的普通文件或单独的分区用于交换空间。交换分区速度更快,但是更改交换文件的大小更容易(无需重新分区整个硬盘,也可以从头开始安装所有内容)。当您知道需要多少交换空间时,就应该使用交换分区,但是如果不确定,可以先使用交换文件,再使用系统一段时间,以便您可以感觉到有多少交换空间有需要时,然后在对分区大小有信心的情况下创建交换分区。
您还应该知道Linux允许一个人同时使用多个交换分区和/或交换文件。这意味着,如果您仅偶尔需要很少数量的交换空间,则可以在这种情况下设置一个额外的交换文件,而不是始终保持分配的总量。
关于操作系统术语的注释:计算机科学通常区分交换(将整个过程写到交换空间中)和分页(一次仅写固定大小的部分,通常一次写几千字节)。分页通常更有效,这就是Linux的工作方式,但是传统的Linux术语仍然谈论交换。