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

虚拟内存是什么意思?

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

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

评论

请参阅:serverfault.com/questions/48582/…

#1 楼

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

地址空间(例如,虚拟内存在流程清单)不花费任何费用;这不是真实的。真正的是RSS(RES)列,它是常驻内存。那就是一个进程占用的实际内存。

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

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

评论


“在启动程序之前和之后检查结果”,或者,使用smem返回的USS(唯一设置大小)。

–休伯特·卡里奥(Hubert Kario)
2012年12月31日上午10:35

那么有没有一种工具可以提供所使用的真实内存量,而不是第三方的工具。

– CMCDragonkai
2014年7月21日在8:23

@CMCDragonkai是的,免费。

– deviantfan
2015年6月2日,9:57

如果我通过java -Xmx16g RunLong启动一个Java进程,该进程将为Java进程保留16Gb内存,那么在top的VIRT中,似乎已计入16Gb。在这种情况下,此16Gb内存的类型是什么,即映射的内存还是..?

–特朗普2020年-正义将到来
16 Mar 11 '16 at 5:15

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

–朱拉·马丁卡(Juraj Martinka)
19年5月27日在20:07

#2 楼

在top(1)手册页上:

o:VIRT-虚拟映像(kb)
任务使用的虚拟内存总量。它包括
所有代码,数据和共享库,以及已被交换的页面和已映射但未使用的页面。
有关更多详细信息,请参见“概述,Linux内存类型”。

(文档的旧版本说明为“ VIRT = SWAP + RES。”其中RES表示常住或使用的物理内存。)
实际上,这是不正确的了(不再)。当它说“交换”时,它还包括程序已映射到其地址空间的文件,这实际上可能会或可能不会消耗实际的RAM。此内存是文件支持的,但实际上并没有交换。
VIRT还包括已分配但尚未用于任何页面的页面。任何处于这种状态的页面都将映射到内核“零页面”(精巧的概念-您应该查找它),因此它可以在VIRT中显示,但实际上并不消耗任何内存。

评论


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

– kapso
2010年5月4日在18:20

基本上是热门节目。...交换:总计1048568k,已使用0k,免费1048568k,已缓存505728k

– kapso
2010年5月4日在18:21

@ user42159这个答案是错误的!男士上装没有'VIRT = SWAP + RES'! -m:VIRT / USED切换报告使用(而不是VIRT)(进程rss和交换总计数的总和)。可惜我不能拒绝这个答案。

–杜莱士
2015年11月4日,下午1:53

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

–Jason S
17年5月10日在23:34

#3 楼

我很清楚地从Mugurel Sumanariu中得到了以下解释:


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

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

SHR指示实际上可以共享多少VIRT大小(内存
或库)。就库而言,不一定意味着整个库都驻留于此。例如,如果仅程序
使用库中的几个函数,则会映射整个库,并且
将在VIRT和SHR中计数,但仅库
文件中包含以下内容的部分实际上,所使用的功能将被加载到
中并计入RES中。


评论


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

–FeRD
19 Mar 22 '19在2:26

#4 楼

ps / top输出中的VIRT列与测量内存使用情况几乎无关。不用担心
Apache重载VIRT与RES内存

https://stackoverflow.com/questions/561245/virtual-memory-usage-from-java-under-linux-too-much-memory二手

评论


谢谢,我感到担心和困惑,因为尽管交换使用率为0%,但虚拟内存列非常高。而且我在使用的全部2.7GB物理内存中只有1.7GB,而虚拟内存很高?

– kapso
2010年5月4日15:56

#5 楼

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

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

有关更多信息,请参见

#6 楼

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

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

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

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

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

评论


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

– David Schwartz
16 Jan 27 '18:34



#7 楼

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