为什么 Linux 奇怪地报告“空闲”内存?

45 linux unix memory-usage

这是一个关于 Unix 操作系统如何报告内存使用情况的规范问题
类似问题:

我有运行Debian 6.0.6 Squeeze 的生产服务器

#uname -a

Linux debsrv 2.6.32-5-xen-amd64 #1 SMP Sun Sep 23 13:49:30 UTC 2012 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

每天cron以 root 身份执行备份脚本:

#crontab -e

0 5 * * * /root/sites_backup.sh > /dev/null 2>&1
Run Code Online (Sandbox Code Playgroud)

#nano /root/sites_backup.sh

Linux debsrv 2.6.32-5-xen-amd64 #1 SMP Sun Sep 23 13:49:30 UTC 2012 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

一切正常,但我注意到 Munin 的内存图显示备份后缓存缓冲区的增加。

然后我只是下载备份文件并删除它们。删除后 Munin 的内存图缓存缓冲区返回到备份前的状态。

这是穆宁图:

外部托管的图像是一个死链接。

vor*_*aq7 61

您遇到了Linux 吃了我的 Ram问题。

不要惊慌。

这不是问题。

您的系统按设计工作。

问题不在于您的操作系统——问题在于您对什么是“空闲”内存的理解。


Unix 系统使用内存不仅仅用于运行程序。内存可能用于:

  • 正在运行的程序(活动/使用)
  • 缓冲传输中的数据(缓冲区)
  • 缓存最近从磁盘读取/写入的数据(缓存)
  • 绝对没有(免费)

下面是对现代 Unix 系统如何报告 RAM 使用情况的简短(并且基本上不完整)的浏览。

什么是可用内存(操作系统定义)

当一个Unix系统报告RAM作为自由它的意思是“我不使用该RAM的任何东西”。
空闲内存实际上毫无价值——它不会让你的系统更快,它只是坐在那里“免费”以防万一需要它。那可能是我上面提到的其他三个项目中的任何一个。

什么是高速缓存和缓冲内存?

缓存和缓冲内存是操作系统用来提高系​​统速度的 RAM。现在运行程序不需要
这个内存,所以你的操作系统使用它来保存它经常需要的数据——例如 C 库(几乎你运行的每个程序都需要)几乎总是保存在内存中,所以系统不必去磁盘查找在屏幕上打印“Hello World”所需的指令。它实际上比这复杂得多——有共享内存、有线内存等——但就我们的目的而言,这个简单的解释就足够了。cache

什么是主动内存?

活动内存是我们理解的“已用”内存的一部分——应用程序使用的 RAM——用于排序电子表格、提供网页、编辑图形等。
“活动”内存最近一直处于“活动状态”—— - 声称它已经使用了其内容(读取或写入)的程序,并且它不被认为是换出的好候选者。

什么是非活动内存?

与活动内存一样,非活动内存是应用程序用于执行任何操作的 RAM。不同之处在于这段内存有一段时间没有被访问过,所以如果推送来了,操作系统认为它可以换出到磁盘,并且(运气好)程序声称它不会再次请求它,所以它永远不会注意到。

什么是“已用”内存(人类定义)

你和我认为的“已用”内存本质上是活动和非活动内存的总和。应用程序当前要求使用的所有 RAM。
只要您安装的 RAM 多于活动和非活动内存的总和(加上顶部 512-1024MB 的良好安全裕度),您就处于一个不错的位置:您的操作系统可能不会达到交换和降低性能.

什么是“自由”内存(人类定义)

你和我认为的“空闲”内存是可用于运行程序的内存。
这比您的操作系统报告的“免费”数字稍微复杂一些。当程序要求 RAM 时,操作系统将尝试以破坏性最小的方式获取该 RAM:

  • 如果有可用内存(无所事事),则将分配 RAM。
  • 如果没有可用的可用内存,操作系统将蚕食缓存和缓冲区空间:缓冲池中最近最少/最不常访问的内容将被丢弃,并将该 RAM 分配给程序。
  • 如果没有缓冲区/缓存 RAM 来蚕食交换器将查看非活动内存并选择它认为最不可能被访问的区域。该数据将被调以交换(磁盘),并将新释放的 RAM 分配给程序。
  • 如果所有非活动 RAM 都被换出,交换器将开始将活动 RAM 放在磁盘上。
    (这就是性能通常会影响到的地方:每次程序在 CPU 上运行时,其换出的位都需要带回 RAM,这意味着必须换出其他程序的活动内存——交换中的高周转率称为颠簸
  • 如果系统已经交换了所有可以交换的东西(并填满了交换分区),或者如果您正在运行一个没有交换分区的系统,就会发生坏事。此时将发生以下两种情况之一:
    • malloc()将失败。这是符合 POSIX 的行为——操作系统会告诉请求 RAM 的程序它不能满足请求。
      该程序可以要求更少的 RAM,或者如果它不能使用较小的内存块,它可以清理并退出。(如果程序写得不好,它只会崩溃。)
    • 如果您使用的是 Linux 机器,OOM-Killer可能会进行帮派式的驱动式杀戮狂欢,终止其他进程以尝试释放足够的 RAM 以满足请求。
      如果你不能通过我在这里的描述和我对链接问题的回答来判断,我认为这是处理问题的一种糟糕的方式。

为什么删除文件时可用内存会增加?

在此问题的示例中,您注意到可以通过删除备份文件来“释放”RAM - 对此的解释非常简单:因为没有使用该文件(没有打开的文件句柄)并且不再可以从文件系统(未链接)操作系统知道没有人会再次访问该数据,它会从文件系统缓存中清除数据。
这使得操作系统报告更多可用内存,但对系统性能没有影响。

  • 另外,应该注意的是,虽然 Windows 通常不会*显示*那么详细,但它有一个*非常*相似的设置。 (2认同)

Jef*_*and 27

这与来自Server 拒绝使用交换分区和此站点上的其他一些类似问题相同的“问题” 。(高内存的Linux服务器的使用量在Linux的内存使用情况Web服务器中的内存不足等)

注意内存消耗来自缓存这一事实。这意味着它将文件保存在内存中。缓存内存是“空闲”内存。您的操作系统不会将内存块留空,而是将最近读取的文件保留在该空间中。如果应用程序确实需要该内存,则该应用程序将使用该内存。在那之前,如果经常引用文件,它就有机会让您不必再次从磁盘读取文件。

根据此图表,在图表的整个持续时间内,您的有效内存消耗根本没有变化。

  • @stan31337 是的,这是可能的,不,您 ** 不应该** 这样做。将此文件保存在内存中不会花费您任何费用。如果您清除所有缓存,则缓存的每个文件都必须从磁盘中再次读取,这只会减慢您的系统速度。让它做它设计要做的事情。 (13认同)
  • @stan31337 当您删除备份文件时,操作系统会自动将其从缓存中踢出(这就是删除后您的空闲内存再次跳跃的原因)--Linux 足够聪明,可以知道未打开且无法打开的文件从文件系统树访问将永远不会被再次访问。就像杰夫说的那样,您绝对不想转储整个 FS 缓存(系统只需要从磁盘重新读取和重新缓存该数据,这实际上会使您的服务器变慢一段时间) (2认同)