5

如何为 64 位 .NET 进程设置 MinWorkingSet 和 MaxWorking 集?

ps 我可以为32位进程设置MinWorkingSet和MaxWorking集,如下:

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);

[DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern IntPtr MyGetCurrentProcess();

// In main():
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, int.MaxValue, int.MaxValue);
4

2 回答 2

6

您所要做的就是像这样更改您的声明:

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", 
    SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, 
    long dwMinimumWorkingSetSize, long dwMaximumWorkingSetSize);

原因是因为函数的定义SetProcessWorkingSetSize

BOOL WINAPI SetProcessWorkingSetSize(
  _In_  HANDLE hProcess,
  _In_  SIZE_T dwMinimumWorkingSetSize,
  _In_  SIZE_T dwMaximumWorkingSetSize
);

请注意,它不使用 a DWORD(作为 32 位整数),而是使用 a SIZE_T,其定义为

指针可以指向的最大字节数。用于必须跨越指针整个范围的计数。此类型在 BaseTsd.h 中声明如下:

typedef ULONG_PTR SIZE_T;

这意味着它是一个 64 位值,因此可以更改为 along并使函数在 64 位系统上工作。此外,来自 MSDN 的标题为“常见 Visual C++ 64 位迁移问题”的部分:

size_ttime_tptrdiff_t是 64 位 Windows 操作系统上的 64 位值。

但是,这有点进退两难,因为您不想编译特定于平台的程序集(那将是一个 PITA)。您可以通过利用上的EntryPoint字段(您已经在做)拥有两个方法声明来解决这个问题:DllImportAttribute

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", 
    SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool SetProcessWorkingSetSize32(IntPtr pProcess, 
    int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", 
    SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool SetProcessWorkingSetSize64(IntPtr pProcess, 
    long dwMinimumWorkingSetSize, long dwMaximumWorkingSetSize);

现在你有两个独立的签名。但是,知道调用哪个签名仍然是一个问题。您不想到处放置条件检查。为此,我建议创建一个为您执行检查并调用它的方法。

您将希望使用上的Is64BitProcess属性来做出此决定。不要使用该属性。您需要前者,因为 32 位进程可以在 64 位操作系统上运行,并且您希望确保您的代码对此具有弹性;仅检查操作系统是否为 64 位并不能为您提供完整的图片。EnvironmentIs64BitOperatingSystem

于 2012-08-30T20:14:33.550 回答
6

不要pinvoke这个,直接使用这个Process.CurrentProcess.MinWorkingSet属性。

非常高的几率,这不会有任何区别。软分页故障是完全正常的,如果机器有足够的 RAM,可以很快解决。在我的笔记本电脑上大约需要 0.7 微秒。你无法避免它们,这是像 Windows 这样的demand_paged虚拟内存操作系统的行为。很便宜,只要有现成的免费页面

但是,如果它使您的程序性能“闪烁”,那么您需要考虑它不易于使用并在另一个进程中触发硬页面错误的可能性。如果必须从另一个进程中窃取 RAM 页面,则分页错误确实会变得昂贵,它的内容必须存储在分页文件中并且必须首先重置为零。这可以很快加起来,数百微秒并不罕见。

“天下没有免费的午餐”的基本规律,你需要运行更少的进程或购买更多的 RAM。后一种选择是明智的选择,今天 8 GB 让您花费大约 75 美元。完全偷窃。

于 2012-08-31T00:25:32.523 回答