了解 Linux 上的虚拟内存使用情况 > 交换 + 物理

了解 Linux 上的虚拟内存使用情况 > 交换 + 物理

我有一个进程在“top”中报告说它分配了 6GB 的常驻内存和 70GB 的虚拟内存。奇怪的是,这台特定的服务器只有 8GB 的​​物理空间和 35GB 的交换空间可用。

来自‘顶级’手册:

   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. (Note: you can define the STATSIZE=1 environment  vari-
      able  and  the VIRT will be calculated from the /proc/#/state VmSize
      field.)

      VIRT = SWAP + RES.

根据这个解释,我预计进程的虚拟内存分配仅限于我的交换+可用的物理内存。

根据“pmap”,该进程的代码、共享库和共享内存部分都非常小 - 不超过 300M 左右。

显然,机器和流程仍然正常运转(尽管速度很慢),那么我在这里遗漏了什么呢?

答案1

它可能需要物理内存中或页面文件中不存在的零内存。

您可能需要查看一些资源:

您的应用程序是否创建了大量的空内存页?如果是这样,您的应用程序可能会从以下方面受益匪浅:

它允许您实时压缩和解压缩内存页面。反过来,您可以将所有内容保留在 RAM 中,而不是交换到磁盘(非常慢)。

答案2

以下是关于虚拟内存与常驻内存的讨论:

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

讨论涉及 Java 进程,但适用于在 Linux 下运行的任何进程。关于 virt 的主要观点是,总数包括一大堆可能永远不会使用的东西。Virt 是 32 位操作系统需要关注的东西(因为进程会达到可寻址空间的限制),但在其他情况下基本上没什么用。如前所述,需要注意的是常驻内存,它将受限于可用的物理 RAM 和交换。

答案3

这可能是因为进程的地址空间虽然大小如您所说,但它实际上并不是由操作系统分配的。

从:http://lwn.net/Articles/428100/

在尝试实现“足够低的开销和没有显著延迟”这一目标的过程中,Go 开发人员做出了一些简化的假设,其中之一就是正在运行的应用程序所管理的内存来自单个几乎连续的地址范围。这样的假设可能会遇到您的编辑器在使用 vi 时遇到的相同问题 - 其他代码可以在范围中间分配部分 - 因此 Go 开发人员采用了相同的解决方案:他们只是在启动时分配他们认为可能需要的所有内存(他们合理地认为 16GB 应该在 64 位系统上足够)。

因此,有时内存管理的方式并不优雅——拥有连续的地址空间可以简化释放未使用的内存。

答案4

我还很惊讶 Linux 允许您分配比物理内存 + 交换空间更多的虚拟内存,但显然它在典型情况下有助于提高性能。

幸运的是,有一个内核调优参数可用于切换内存核算模式。此参数是 vm.overcommit_memory,它指示使用哪种算法来跟踪可用内存。默认值 (0) 使用启发式方法并过度使用虚拟内存系统。如果您希望程序在分配时收到适当的内存不足错误,而不是让您的进程受到随机终止,则应将此参数设置为 2。

http://www.linuxjournal.com/article/10678

相关内容