6

SysInternals の VMMap を使用して、WinXP 上の Win32 C++ プロセスによって割り当てられたメモリを調べています。割り当てられたメモリの一部が予約されているがコミットされていない割り当てが多数見られます。私が読んでテストした限りでは、C++ プログラムで使用される一般的なメモリ アロケータ (malloc、new、LocalAlloc、GlobalAlloc など) はすべて、常に完全にコミットされたメモリ ブロックを割り当てます。ヒープは、メモリを予約するが、必要になるまでコミットしないコードの一般的な例です。これらのブロックの一部は Windows/CRT ヒープであると思われますが、これらの種類のブロックは、ヒープに予想されるよりも多いようです。私のプロセスでは、サイズが 64k から 8MB のこれらのブロックが 30 個程度あります。私のコードは、VirtualAlloc を意図的に呼び出して、予約されたコミットされていないメモリを割り当てることはありません。

VMMap の例をいくつか示します: http://www.flickr.com/photos/95123032@N00/5280550393/

その多くが予約されているがコミットされていないメモリのブロックを割り当てるには、他に何がありますか? プロセスに 30 個のヒープがあることは理にかなっていますか? ありがとう。

4

3 に答える 3

9

私はそれを理解しました - への呼び出しによって割り当てられるのは CRT ヒープですmalloc。を使用して大量のメモリ (2 MB など) をmalloc割り当てると、コミットされたメモリ ブロックが 1 つ割り当てられます。しかし、より小さなチャンク (たとえば 177kb) を割り当てると、1 MB のメモリ チャンクが予約されますが、要求されたもの (たとえば、177kb の要求に対して 184kb) のみがコミットされます。

その小さなチャンクを解放すると、その大きな 1 MB チャンクは OS に返されません。4k 以外はすべてコミットされていませんが、1 MB 全体が予約されています。その後再度呼び出すmallocと、要求を満たすためにその 1 MB のチャンクを使用しようとします。すでに予約されているメモリで要求を満たすことができない場合は、以前の割り当ての 2 倍の新しいメモリ チャンクが割り当てられます (私の場合は 1 MB から 2 MB になりました)。この倍増のパターンが続くかどうかはわかりません。

解放されたメモリを実際に OS に戻すには、 を呼び出すことができます_heapmin。これにより、将来の大規模な割り当てが成功する可能性が高くなると思いますが、それはすべてメモリの断片化に依存し、おそらく割り当てが失敗した場合 (?)、heapmin が既に呼び出されている可能性があります。heapmin がメモリを解放し (時間がかかる)、malloc が必要になったときに OS からメモリを再割り当てする必要があるため、パフォーマンス ヒットも発生します。この情報は Windows/32 XP 用であり、マイレージは異なる場合があります。

更新: 私のテストでは、heapmin はまったく何もしませんでした。また、malloc ヒープは 512kb 未満のブロックにのみ使用されます。malloc ヒープに MB の連続した空き領域がある場合でも、512kb を超える要求には使用されません。私の場合、この解放された、未使用でありながら予約済みの malloc メモリが、プロセスの 2 GB のアドレス空間の大部分を食い尽くし、最終的にメモリ割り当ての失敗につながりました。また、heapmin はメモリを OS に返さないため、プロセスを再起動するか、独自のメモリ マネージャーを作成する以外に、この問題の解決策は見つかりませんでした。

于 2011-01-04T21:49:09.977 に答える
0

プロセスにロードされた DLL でしょうか? DLL (および実行可能ファイル) は、プロセスのアドレス空間にマップされたメモリです。これは最初はスペースを予約するだけだと思います。スペースは、ページファイルではなく、(少なくとも最初は) ファイル自体によって支えられています。

実際に触れたコードだけがページインされます。用語を正しく理解していれば、それがコミットされたときです。

これを確認するには、アプリケーションをデバッガーで実行し、読み込まれたモジュールを調べて、それらの場所とサイズを VMMap に表示されているものと比較します。

于 2010-12-21T23:32:13.670 に答える