17

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

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

4

3 回答 3

18

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

于 2009-06-24T15:21:31.487 回答
14

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

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

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

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

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

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

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

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

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

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

实现从实现的角度来看,非分页 CLR 主机使用 SetProcessWorkingSetSizeSetProcessWorkingSetSizeEx(在 Windows Server 2003 及更高版本上)和VirtualLock API 来确保它分配的内存被锁定到物理内存中。请注意,使用上述 API 不能 绝对保证不会发生分页;相反,它 最大限度地减少了它在非常特殊的情况下发生的可能性。在我们进行的一些负载测试中,即使整个系统因缺乏物理内存而被占用,也没有观察到进程中的页面错误 使用非分页 CLR 主机。

于 2009-07-02T07:15:41.737 回答
0

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

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

于 2009-07-05T21:12:38.013 回答