我可以告诉 Windows 不要换出特定进程的内存吗?

Posted

技术标签:

【中文标题】我可以告诉 Windows 不要换出特定进程的内存吗?【英文标题】:Can I tell Windows not to swap out a particular processes’ memory? 【发布时间】:2010-11-05 13:23:15 【问题描述】:

有没有办法告诉 Windows 它不应该将特定进程的内存换出到磁盘?

它是一个内存使用量相当大的 .Net Windows 服务。我有很多物理 RAM,但操作系统似乎将部分进程内存移动到页面文件。

【问题讨论】:

Windows 在最近最少访问的基础上从进程工作集中移动页面。通常这会产生良好的结果,但特定的用例可能需要控制。在您执行此操作之前,请阅读 Windows Internals(开始)以更好地了解您要执行的操作。 我支持评论。在大多数情况下,试图超越 Windows 内存管理器会导致性能下降。 关键问题:为什么这(“将部分进程内存移动到页面文件”)仍然是个问题? 我认为质疑这样的动机是一种不好的形式......开发人员必须坚持的约束通常不是他们选择和坚定的要求。 @RandomNickName42:相信我,我理解程序员面临的压力,我也戴着那顶帽子。然而,作为一名程序员,重要的是要知道我什么时候做的事情被认为是不寻常的,并且知道什么情有可原的情况要求它......我实际上是想弄清楚是否需要在 RAM 中维护可执行文件作为以及是否会影响文件 IO 缓冲区... 【参考方案1】:

您可以使用VirtualLock 来防止内存被分页到磁盘,但我真的认为您最好让操作系统管理系统的内存。它非常擅长,除非我真的知道自己在做什么,否则我不会再猜测操作系统为什么要将东西交换到磁盘。

【讨论】:

如果它做得很好,我们会看到这么多应用程序需要几秒钟才能打开上下文菜单,只是因为某些复制操作处于打开状态并阻塞了分页 io? 禁用分页要求对于演示应用程序是合法的,特别是对于流媒体应用程序,对于实时音频应用程序,这是不可避免的要求,因为 ASIO 和其他现代音频驱动程序实际上并没有对缓冲区状态进行任何智能处理(以减少延迟),因此任何意外延迟都可能会破坏可听性并引入非常不需要的效果。【参考方案2】:

默认情况下,VirtualLock 会很快用完配额,即使您允许用户使用(默认情况下,“锁定内存页面”的安全策略设置没有条目(甚至没有管理员)。

如果您进行了配置,您还需要设置“调整进程的内存配额”。

这个问题有点含糊,你想防止VM空间的哪一部分被换出?堆/堆栈/模块的?...?

总的来说,我过去使用的一种解决方案是创建一个 DLL,其中包含一个 READ + WRITE 的大部分,不可移动,如果需要,您也可以将其标记为 EXECUTE 和 SHARED,但我会 HeapCreate 到该模块的部分,允许我将其用作堆。

您可以查找确切的位来设置here,IMAGE_SCN_MEM_NOT_PAGED 看起来可以解决问题。

如果您使用此位标记所有模块和部分,Windows 模块加载器将不会收取特定的用户配额或要求在您部署代码的每个系统上修改策略设置。您还需要在一个特殊的 shim 中编写代码,以提供对您在这些 NON_PAGEABLE dll 中创建的 HEAP 的访问权限。

这有点工作,但过去对我来说效果很好,我增加了将内存共享给基于同一地址的多个进程的要求。

我认为最简单的方法是完全禁用您的页面文件。但在此之前,如果您使用的是 Vista/2008+ 操作系统,您看到的交换可能是由于 superfetch 造成的,这可能会主动“调整”您的系统,假设在不久的将来您需要使用一个或另一个应用程序。其他一些简单的任务是停止未使用的服务,例如搜索,这可能会索引大量文件,您还应该进入配置系统任务的“任务调度程序”,默认情况下,大多数系统默认有几十个将所有 Dr. Watson 转储传输到 MS、对驱动器进行碎片整理以及许多其他可能非常占用内存的类型操作的操作。

您可以提供更多详细信息以获得更好的答案...但另一个建议是简单地购买大型固态驱动器并将其专门用于交换,请注意这些会随着时间的推移而降低整体性能由于坏块映射在所有现有 SSD 技术中都很常见。

我最近在他们的页面上发现了一个名为 "non-paged clr host" 的 codeplex 项目:

实施从实施的角度来看, 非分页 CLR 主机使用 SetProcessWorkingSetSize, SetProcessWorkingSetSizeEx(在 Windows Server 2003 及更高版本)和 VirtualLock 确保分配内存的 API 它被锁定在物理内存中。 请注意,使用上述 API确实 保证绝对肯定 不会发生分页;相反,它 尽量减少发生的几率 非常特殊的情况。在一些 我们进行的负载测试,甚至 当整个系统被占用时 由于缺少物理内存,没有页面 在过程中观察到故障 使用非分页 CLR 主机。

【讨论】:

【参考方案3】:

您确定相关页面正在从内存中清除吗? VM 子系统可能会主动将脏页写入磁盘,而不会被驱逐,因此未来潜在的分配具有更低的延迟。

此外,如果系统正在执行大量 IO,则将有问题的内存用于缓冲区而不是应用程序数据可能会更好地提高性能,如 Martin Pool 所述

【讨论】:

MS 最近发布了一个工具 DynCache,它允许您在这些场景中预先配置或设置一些首选项,blogs.msdn.com/ntdebugging/archive/2009/02/06/… & sqlblogcasts.com/blogs/grumpyolddba/archive/2009/03/18/… Gheeze 我讨厌撕破你,但我真的需要积分;)。您引用的参考是针对 linux 的,如果没有明确说明,白话的细微差异可能会非常令人困惑......如果您参考(msdn.microsoft.com/en-us/library/cc644950(VS.85).aspx),“当 FILE_FLAG_NO_BUFFERING 与 FILE_FLAG_OVERLAPPED 结合使用时,这些标志会提供最大的异步性能,因为I/O 不依赖于内存管理器的同步操作。但是,一些 I/O 操作需要更多时间,因为数据没有保存在缓存中。 - 所以 Windows = NO_BUFFER > * :)

以上是关于我可以告诉 Windows 不要换出特定进程的内存吗?的主要内容,如果未能解决你的问题,请参考以下文章

android内存管理

页面置换算法

Windows 进程的内存映射是啥样的?

页面分配策略

页面分配策略

Linux性能优化实战:系统的swap变高(08)