5

MinWorkingSet および MaxWorking セットを 64 ビット .NET プロセスに設定するにはどうすればよいですか?

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

DWORD(32ビット整数として)を使用するのSIZE_Tではなく、 :として定義されることに注意してください。

ポインタが指すことができる最大バイト数。ポインタの全範囲にまたがる必要があるカウントに使用します。このタイプは、BaseTsd.hで次のように宣言されています。

typedef ULONG_PTR SIZE_T;

これは、64ビット値であることを意味します。したがって、に変更して、long64ビットシステムで関数を機能させることができます。また、MSDNの「一般的なVisual C ++64ビット移行の問題」というタイトルのセクションから:

size_ttime_t、およびptrdiff_tは、64ビットWindowsオペレーティングシステムでは64ビット値です。

ただし、これには、プラットフォーム固有のアセンブリ(PITA)をコンパイルする必要がないという点で、少しジレンマがあります。これを回避するには、クラスのEntryPointフィールド(既に実行している)を利用して、次の2つのメソッド宣言を作成します。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);

これで、2つの別々の署名ができました。ただし、どの署名を呼び出すかを知ることは依然として問題です。どこにでも条件付きチェックを配置したくありません。そのためには、チェックを実行して呼び出すメソッドを作成することをお勧めします。

この決定を行うには、クラスのIs64BitProcessプロパティを使用する必要があります。プロパティを使用しないでください。32ビットプロセスは64ビットオペレーティングシステムで実行できるため、前者が必要です。また、コードがそれに対応していることを確認する必要があります。オペレーティングシステムが64ビットであるかどうかを確認するだけでは、全体像はわかりません。EnvironmentIs64BitOperatingSystem

于 2012-08-30T20:14:33.550 に答える
6

これをピンボークしないでくださいProcess.CurrentProcess.MinWorkingSet。プロパティを直接使用してください。

これで何も変わらない可能性が非常に高いです。ソフト ページング フォールトは完全に正常であり、マシンに十分な RAM がある場合は非常に迅速に解決されます。私のラップトップでは ~0.7 マイクロ秒かかります。それらを避けることはできません。これは、 Windows のようなdemand_paged仮想メモリ オペレーティング システムの動作です。すぐに利用できる無料のページがある限り、非常に安い.

ただし、プログラムのパフォーマンスが「低下」する場合は、すぐに利用できず、別のプロセスでハード ページ フォールトが発生する可能性を考慮する必要があります。RAM ページを別のプロセスから盗む必要があり、そのコンテンツをページング ファイルに保存し、最初にゼロにリセットする必要がある場合、ページング フォールトはコストがかかります。数百マイクロ秒も珍しくありません。

「無料のランチはない」という基本法則では、実行するプロセスを減らすか、RAM を購入する必要があります。後者のオプションは賢明な選択であり、8 ギガバイトで現在は約 75 ドルの節約になります。完全盗み。

于 2012-08-31T00:25:32.523 に答える