1

によって割り当てられたスタック領域CreateThreadが の使用を妨げる可能性はありVirtualAllocますか? スタック領域の割り当てが許可されている場所を正確に説明している議論やドキュメントが見つかりません...

以下は、私の質問をより正確に示しています。

uint8_t *baseA = (uint8_t*)VirtualAlloc(NULL,1,MEM_RESERVE,PAGE_NOACCESS);

// Create a thread with the default stack size
HANDLE hThread = CreateThread(NULL,0,SomeThreadProc,NULL,NULL,NULL);

// Possibly create even more threads here.

// Can this ever fail in the absence of other allocators? It doesn't here...
uint8_t *baseB = (uint8_t*)VirtualAlloc(NULL,1,MEM_RESERVE,PAGE_NOACCESS);

// Furthermore, in this test, baseB-baseA == 65536 (unless the debugger did something),
// so nothing appeared between baseA and baseB... not even enough space for the
// full 64kb of wastage, as baseA points to 4096 bytes by itself

実際に の類似物を使用ている場合VirtualAlloc、特定のプロセスで Windows がスタック領域を割り当てる方法を変更する方法はありますか?

4

2 に答える 2

3

スタック空間は、プロセスのアドレス空間のどこにでも割り当てることができます。現在、これに関するドキュメントはなく、将来そのようなドキュメントが表示される可能性は低いです。

スレッドの作成と仮想割り当ては独立していると安全に想定できます。そうしないと、多くのものが壊れてしまいます。アロケーターは、重複するアドレス範囲を提供できません。これは考えられません。問題は別の場所にあります。

相関関係のように見える唯一のもの - 使用されるメモリの量と仮想アドレス空間の断片化。この場合、最新のリクエストは単純に失敗します。

私はメモリ分析ユーティリティに取り組みました。

ここに画像の説明を入力

この図は、割り当てのサイズごとの仮想割り当ての数の分布を示しています。

ここに画像の説明を入力

これは、32 ビット プロセスのアドレス空間の内容の例です (青 - コミット済み、マゼンタ - 予約済み、緑は空きメモリ)。

ここに書いたことは実体験に基づいています。

于 2012-08-11T02:37:56.703 に答える
1

Windows NT カーネルは、高い割り込み優先度でメモリ割り当て操作をスレッド セーフな方法で処理します。

つまり、プロセスの 1 つのスレッドのみが同時にメモリを割り当てることができるため、すべての割り当てプロセスが (理論的には) スレッド セーフになります。スタック割り当てと仮想割り当ての間に干渉があってはなりません。

また、1GBのスペースを割り当てることができますが、プログラムはまだ2MBのRAMしか使用しないことを覚えておく必要があります。

これは、Windows が仮想空間を「事前に割り当てる」ためですが、使用する (書き込む) までは割り当てられません。

実際には、メモリ管理はもっと複雑ですが、割り当てが処理される限り、Windows がプロセスを 1 つのコアにロックし、他のすべてのスレッドの割り当て要求を遅らせるため、割り当て操作が干渉しないことを今のところ確信でき​​ます。(デッドロック)

*編集: これは、数百万の小さなビットを割り当てる場合、割り当てと割り当て解除がパフォーマンスを必要とするプロセスであることも意味します。このデッドロック動作のため、より大きなメモリ領域を割り当て/割り当て解除することを常にお勧めします。

于 2012-08-11T02:28:47.773 に答える