How to set MinWorkingSet and MaxWorkingSet in a 64-bit .NET process?

前端 未结 2 1578
南旧
南旧 2021-01-13 07:48

How do I set MinWorkingSet and MaxWorking set for a 64-bit .NET process?

p.s. I can set the MinWorkingSet and MaxWorking set for a 32-bit process, as follows:

<
相关标签:
2条回答
  • 2021-01-13 08:19

    All you have to do is change your declaration like so:

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

    The reason is because of the definition of the SetProcessWorkingSetSize function:

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

    Note that it doesn't use a DWORD (as 32-bit integer) but a SIZE_T, which is defined as:

    The maximum number of bytes to which a pointer can point. Use for a count that must span the full range of a pointer. This type is declared in BaseTsd.h as follows:

    typedef ULONG_PTR SIZE_T;
    

    This means that it's a 64-bit value, hence the ability to change to a long and have the function work on 64-bit systems. Also, from the section of MSDN titled "Common Visual C++ 64-bit Migration Issues":

    size_t, time_t, and ptrdiff_t are 64-bit values on 64-bit Windows operating systems.

    However, this presents a bit of a dilemma, in that you don't want to have to compile platform-specific assemblies (that would be a PITA). You can get around this by taking advantage of the EntryPoint field on the DllImportAttribute class (which you're already doing) to have two method declarations:

    [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);
    

    Now you have two separate signatures. However, knowing which signature to call is still an issue. You don't want to place conditional checks everywhere. To that end, I'd recommend creating a method that performs the check for you and call that.

    You'll want to use the Is64BitProcess property on the Environment class to make this determination. Don't use the Is64BitOperatingSystem property. You want the former because 32-bit processes can be run on 64-bit operating systems, and you want to make sure that your code is resilient to that; just checking to see if the operating system is 64 bit doesn't give you the entire picture.

    0 讨论(0)
  • 2021-01-13 08:23

    Don't pinvoke this, just use the Process.CurrentProcess.MinWorkingSet property directly.

    Very high odds that this won't make any difference. Soft paging faults are entirely normal and resolved very quickly if the machine has enough RAM. Takes ~0.7 microseconds on my laptop. You can't avoid them, it is the behavior of a demand_paged virtual memory operating system like Windows. Very cheap, as long as there is a free page readily available.

    But if it "blips" you program performance then you need to consider the likelihood that it isn't readily available and triggered a hard page fault in another process. The paging fault does get expensive if the RAM page must be stolen from another process, its content has to be stored in the paging file and has to be reset back to zero first. That can add up quickly, hundreds of microseconds isn't unusual.

    The basic law of "there is no free lunch", you need to run less processes or buy more RAM. With the latter option the sane choice, 8 gigabytes sets you back about 75 bucks today. Complete steal.

    0 讨论(0)
提交回复
热议问题