或者再次从映射内存重新读取数据会更快,因为操作系统可能会实现自己的缓存?
事先不知道数据的性质,假设文件读取是随机的。
答案 0 :(得分:3)
答案是高度针对特定操作系统的。一般来说,缓存这些数据是没有意义的。 “缓存”数据以及内存映射都可以随时分页。
如果存在任何差异,它将特定于操作系统 - 除非您需要这种粒度,否则缓存数据是没有意义的。
答案 1 :(得分:3)
我想提一下我读过的关于这个主题的一些事情。答案是 no ,你不想再猜测操作系统的内存管理器。
第一个来自于您希望您的程序(例如MongoDB,SQL Server)根据可用RAM的百分比来限制内存的想法:
Don't try to allocate memory until there is only x% free
有时,客户会要求一种方法来设计他们的程序,因此它会继续消耗RAM,直到只有x%可用。这个想法是他们的程序应该积极地使用RAM,同时仍留下足够的RAM(x%)用于其他用途。除非你设计的系统是你在计算机上运行的唯一程序,否则这是一个坏主意。
(阅读文章解释为什么它不好,包括图片)
接下来来自Varnish的作者和反向代理的一些注释:
Varnish Cache - Notes from the architect
鱿鱼精心设计的内存管理会发生什么呢?它会与内核精心设计的内存管理斗争,就像任何内战一样,从来没有做过任何事情。
这是怎么回事:Squid在" RAM"中创建了一个HTTP对象。它会在创建后快速使用一段时间。然后经过一段时间后,它不再受到点击,内核会注意到这一点。然后有人试图从内核获取内存,内核决定将那些未使用的内存页面推送到交换空间,并对程序实际使用的某些数据更合理地使用(cache-RAM)。然而,这是在没有鱿鱼知道的情况下完成的。 Squid仍然认为这些http对象在RAM中,并且它们将是它尝试访问它们的第二个,但在此之前,RAM用于生产效率。
想象一下,执行缓存来自内存映射文件的内容。在未来的某个时刻,内存持有"缓存"将被换成磁盘。
接下来是您希望从"缓存"执行查找的时间。记忆,而不是真实的"记忆。您尝试访问"缓存",并且由于它已从RAM中换出,硬件会引发PAGE FAULT
,并且缓存会被交换回RAM。
最后,您要释放缓存(可能是您的程序正在关闭)。如果"缓存"已被换出,操作系统必须首先将其重新交换,以便可以释放它。如果您只是取消映射了内存映射文件,一切都消失了(不需要交换)。
再次来自Raymon Chen:如果您的申请正在关闭 - 已经关闭:
When DLL_PROCESS_DETACH tells you that the process is exiting, your best bet is just to return without doing anything
我经常使用不遵循此规则的程序。该程序 在它的生命过程中分配大量的记忆,当我 退出程序,它有时会在那里坐几分钟 以100%CPU旋转,有时搅拌硬盘(有时候 都)。当我打破调试器以查看发生了什么时,我 发现程序没有做任何有效的事情。这是公正的 有条不紊地释放它在分配期间分配的每个最后一个字节 它的一生。
如果我的电脑没有很大的内存压力,那么大部分时间都是如此 程序在其生命周期中分配的记忆还没有 分页,所以每个最后一滴内存释放是一个CPU限制 操作。另一方面,如果我开始构建或完成 其他内存密集的东西,然后大部分内存的程序 在其生命周期中分配的已被分页,这意味着 程序会将所有内存从硬盘驱动器中回页,就这样 它可以免费打电话。听起来有点恶意,实际上。 "加油 在这里,我可以告诉你离开。"
所有这些肛门记忆管理都毫无意义。这个过程 正在退出。当地址空间为时,将释放所有内存 销毁。不要浪费时间,只是退出。
现实情况是,程序不再在 &#34; RAM&#34; 中运行,它们运行在 内存 < / strong> - 虚拟内存。
可以使用缓存,但您必须使用操作系统的虚拟内存管理器:
访问:
比访问
贵得多换句话说:您不需要缓存数据,您需要更加本地化的数据结构。
如果您将重要数据限制在一个4k页面,那么您将在VMM中发挥更好的作用; Windows 是您的缓存。
当您添加64字节四字对齐的缓存行时,更有动力调整您的数据结构布局。但是,你不希望它太紧凑,或者你开始从False Sharing开始遭受缓存刷新的性能损失。