如何在64位.NET进程中设置MinWorkingSet和MaxWorkingSet?
如何为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);
您所要做的就是更改您的声明,如下所示:
[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 );
请注意,它不使用DWORD
(作为32位整数)而是使用SIZE_T
,它定义为 :
指针可指向的最大字节数。 用于必须跨越指针的整个范围的计数。 此类型在BaseTsd.h中声明如下:
typedef ULONG_PTR SIZE_T;
这意味着它是一个64位值,因此能够更改为long
并使该function在64位系统上运行。 另外,从MSDN标题为“ Common Visual C ++ 64位迁移问题 ”的部分:
size_t , time_t和ptrdiff_t是64位Windows操作系统上的64位值。
但是,这会带来一些困境,因为您不希望编译特定于平台的程序集(即PITA)。 您可以通过利用DllImportAttribute
类 (您已经在做的)上的EntryPoint
字段来解决这个问题,以获得两个方法声明:
[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);
现在您有两个单独的签名。 但是,知道要调用哪个签名仍然是个问题。 您不希望在任何地方进行条件检查。 为此,我建议创建一个方法来执行检查并调用它。
您将要使用Environment
类上的Is64BitProcess
属性来进行此确定。 不要使用Is64BitOperatingSystem
属性 。 您需要前者,因为32位进程可以在64位操作系统上运行,并且您希望确保您的代码具有弹性; 只是检查操作系统是否为64位并不能给你全部图片。
不要对此进行说明,只需直接使用Process.CurrentProcess.MinWorkingSet
属性即可。
非常高的赔率,这不会有任何区别。 如果机器有足够的RAM,软分页故障是完全正常的并且很快就能解决。 我的笔记本电脑需要约0.7微秒。 你无法避免它们,它是像Windows这样的demand_paged虚拟内存操作系统的行为。 非常便宜,只要有免费页面随时可用 。
但如果它“闪烁”你编程性能,那么你需要考虑它不可用的可能性并在另一个进程中触发硬页面错误。 如果必须从另一个进程中窃取RAM页面,其页面内容必须存储在页面文件中并且必须首先重置为零,否则寻呼错误会变得昂贵。 这可以很快加起来,数百微秒并不罕见。
“没有免费午餐”的基本法则,你需要运行更少的流程或购买更多的内存。 后一种选择是理智的选择,8千兆字节让你今天回来大约75美元。 完全偷。