2017-03-02 16 views
2

.NET dll(外部関数)を呼び出しているネイティブのC++アプリケーションがあります。管理対象の呼び出し時に割り当てられたスタック全体が割り当てられます/ stackリンカオプションを使用して指定されたスレッドの場合、ネイティブ関数呼び出しのみを行うと、計算に必要なスタックが割り当てられます。混在モードでのメモリ使用量が多すぎる

以下

は80メガバイトに設定/スタックオプションを使用すると、および管理外部関数の呼び出しと私の観測

です。 enter image description here

/stackオプションを1MBに設定し、管理外部機能を呼び出します。 enter image description here

/stackオプションを80MBに設定し、ネイティブ内部関数を呼び出します。 enter image description here

.Net外部関数を呼び出すと、GCに関連する余分なスレッドがいくつかあります。また、アプリケーション内のスレッドは.Net外部関数を呼び出さない場合と比較して、かなり多くのスタック領域を使用しています。管理スタックがネイティブスタックの上にあるかどうかはわかりません。誰かが私たちが.Net外部関数への呼び出しを行い、混合モードアプリケーションでのメモリ管理を行うときに、スレッドのフルスタックが割り当てられている理由を知ってもらえますか?

答えて

2

[OK]ようやく答えが見つかりました。

管理対象スレッドが作成されるとすぐに管理対象スレッド用のスタックメモリ全体がコミットされます。ネイティブスレッドが管理対象スレッドになると、遅延が遅くなります。これは、スタックオーバーフローが実行エンジンによって予測可能に処理されることを保証するために行われます。

マネージコードでは、System.Threading.Threadクラスのコンストラクターには、maxStackSizeパラメーターを受け入れる2つのオーバーロードが用意されています。フルスタックはすべての管理対象スレッドの作成時にコミットされるため、maxStackSizeパラメータは予約サイズとコミットサイズの両方を表します。これらは実質的に同じです。ただ、明確にする

は、スタック上のメモリを使用するための3つのステップがあります:プロセスにおけるスタック用

準備仮想アドレス空間は がページ

通常のデフォルトの動作を使用するページをコミット Win32プログラムは、スレッドが起動するときにちょうど1回実行することです。スタックフレームを追加するときに、システムには空き仮想メモリがありません。

手順2を実行することにより、手順3が失敗しないように、CLRによってメモリが確保されます。

これに関する有用な情報は、依然として高く評価されています。 ありがとうございます。

関連する問題