我一直将 Linux 中的缓存内存(如 free -m 中的)理解为内存页面,如果再次需要它们,可以重用它们,或者如果新应用程序需要更多内存,则可以快速释放它们(我发现本文几年前有帮助)。
看起来可执行文件(例如,雷鸟之类的程序)和数据(例如,日志文件的内容)都可以被缓存。事实上,我认为 *nix 上的文本文件和可执行文件之间没有区别。
我可以看到它如何适用于变化不大的数据(例如文本文件),但是它如何适用于本质上是动态的程序呢?当然,缓存内存不能恢复动态分配的对象吗?那么是否只有字节码(或脚本情况下的指令)被缓存?
编辑1
通过缓存内存,我指的是当我运行“free”时“cached”列下的内存:
$ free -m
total used free shared buffers cached
Mem: 7985 6650 1334 0 150 3201
-/+ buffers/cache: 3298 4686
Swap: 13178 2 13176
编辑2
感谢 ls-lrt 给了我我错过的提示。正如 SE 上的这个回复明确提到的那样(应该先在那里搜索),“缓存内存是磁盘缓存由VFS使用”。这意味着对于可执行文件,此列下仅表示指令(字节码、脚本行等),与动态分配的内容无关。我的印象是整个内存页面(包括动态创建的对象)都被“缓存”。
编辑3
关于的好例子使用磁盘缓存。
答案1
free中显示的缓存是文件系统缓存。在文件系统级别,一切都只是数据的八位位组。无论是应用程序还是文件数据,没有区别在那个级别。虽然可以重新加载已从文件缓存中换出的可执行文件(可执行文件是不是写入交换文件,它们只是被踢出内存),这种情况很少见,因为文件缓存通常首先被牺牲。
现在,请清楚文件缓存(如空闲内存和正在运行的程序可能涉及的任何其他类型的内存)之间的区别。因为尚不清楚“缓存内存无法恢复动态分配的对象”是什么意思。应用程序使用的任何内存都是不是与文件缓存有关。文件缓存不会缓存应用程序的任何类型的内存分配。文件缓存只是磁盘和操作系统之间的中介。
回答这个严肃的问题:“那么缓存的只是字节码(或脚本中的指令)吗?”
文件缓存仅缓存磁盘上的八位字节。它不关心应用程序使用什么内存。
答案2
Linux内核对待内存中各类数据的方式基本上没有什么区别:内核关心这个的部分称为“虚拟内存子系统”,它只关心某一部分内存是否正在使用通过或不通过程序。
Linux 内核将可用 RAM 划分为称为“页面”的小块。然后将页面分类为“正在使用”(例如:包含当前正在运行的程序的代码或数据的页面)和“未使用”页面。对于“正在使用”的页面,它们是否包含可执行代码、文本数据、Java 字节码或其他内容并不重要——唯一重要的是它们“正在使用”:它们需要位于 RAM 中,因为该数据不断被访问。
由于 RAM 是可用的最快的存储设备,让“未使用的”页面处于非活动状态是一种浪费,因此内核“回收”未使用的页面来缓存已从磁盘获取并可能很快再次需要的数据。内核有一些算法来进行这种预测; I/O 系统性能在很大程度上取决于该算法能否很好地预测计算机的实际工作负载。
此外,为了加速 I/O 操作,部分 RAM 将用于缓冲正在写入磁盘的数据:您可能已经注意到,当您将大文件复制到慢速磁盘(例如 USB Stick),该cp
命令在数据完全写入设备之前完成:发生这种情况正是因为内核在“空闲”内存中保存了一些数据以加速(缓慢的)写入操作;数据将在几秒钟后写回磁盘,此时cp
程序可能已经完成。一旦数据写入磁盘,这些页面将再次被视为空闲(并重新用于缓存数据,或者在需要时移动到“使用中”池)。
正如您所指出的,“缓存”页面可以(相对)快速地被内核回收,以防需要为“使用中”数据分配更多页面,因为“缓存”页面仅保存以下数据:可从磁盘获取(缓存的数据将在需要时再次从磁盘获取)。
进一步阅读: