2

私の問題は、変更できない32ビットDLLがあることです。DLLは、通常の操作で約1.5ギガ程度のメモリを必要とする場合があります。

C ++ /アンマネージコードテストプログラムを使用すると、DLLは約2ギガでメモリ不足になります。これは、32ビットプロセスで使用可能な最大サイズであるため、予想されます。したがって、DLLは通常の操作で正常に動作します。

それ自体が約250MBかかるC#アプリケーションからDLLをIP /呼び出しすると、プロセス全体が約1.4ギガに達するとDLLがエラーになります。私の質問は、P / Invokeが32ビットプロセスで使用するメモリを少なくすることですか?もっとあげる方法はありますか?

編集:P / Invoked関数は、実際には私のメインによって参照されているC#アセンブリから呼び出されます。これが何らかの形で関連しているかどうかはわかりません。

4

2 に答える 2

3

違いはおそらく、管理対象プログラムのニーズが管理対象外プログラムよりも大きいためです。そのため、DLLに残されているリソースは少なくなります。メモリが残っているように見えても、プログラムのメモリが不足する可能性があります。これは、アドレススペースが断片化されており、仮想メモリアロケータが割り当て要求を満たすのに十分な大きさの連続したメモリブロックを見つけることができない場合に発生します。

私が思うに、あなたができることはあまりありません。管理されたプロセスがより少ないリソースを消費するようにしようとすると、幸運が訪れるとは思えません。64ビットシステムで実行していて、プロセスが大容量アドレスを認識している場合、プロセスは4GBのメモリにアクセスできます。

.net実行可能ファイルにマークを付けるLARGEADDRESSAWAREと役立つ場合があります。詳細については、別のSOの質問を参照してください:.NETアプリケーションを「大容量アドレス対応」にする方法は?EDITBIN要約すると、実行可能ファイルをマークするためにツールを実行する必要があります。

EDITBIN /LARGEADDRESSAWARE YourExeName.exe

ただし、32ビットOSでは、2GBの制限にかなり悩まされていることに注意してください。はい、/ 3GBスイッチを使用してシステムを起動できますが、これは通常はお勧めできません。

他の明白なオプションは、プロセス外のCOMサーバーにDLLを格納することです。別のプロセスに配置することで、.netランタイムをプロセスから除外し、空腹のDLL用にできるだけ多くのスペースを残すことができます。

于 2012-12-06T15:13:26.870 に答える
1

これは、C ++アプリケーションにLARGEADDRESSAWAREオプションが設定されていて、c#アプリには設定されていないために発生する可能性があります

C ++アプリでは、ここで定義されます->リンカー->システム->大きなアドレスを有効にする= "Yes / LARGEADDRESSAWARE"

次のビルド後のイベントを追加してみてください

call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86
"$(DevEnvDir)..\..\vc\bin\EditBin.exe" "$(TargetPath)"  /LARGEADDRESSAWARE
于 2012-12-06T15:24:05.683 に答える