質問

sysinternalsのvmmapを使用して、winxpのwin32 c ++プロセスによって割り当てられたメモリを調べます。割り当てられたメモリの一部が予約されているがコミットされていない割り当ての束が表示されます。私が知る限り、私の読書とテストから、C ++プログラムで使用されるすべての共通メモリアロケーター(Malloc、New、new、localAlloc、GlobalAlloc)は、常に完全にコミットされたメモリブロックを割り当てます。ヒープは、メモリを留保するが、必要になるまでそれをコミットしないコードの一般的な例です。これらのブロックのいくつかはWindows/CRTヒープであると思いますが、ヒープの場合よりも多くのこれらのタイプのブロックがあるようです。私のプロセスでは、これらのブロックのうち30件、サイズが64Kから8MBの間で見られます。私のコードは、予約済みのメモリを割り当てるためにVirtualAllocを意図的に呼び出すことは決してないことを知っています。

VMMAPの例をいくつか紹介します。 http://www.flickr.com/photos/95123032@n00/5280550393/

そのようなメモリのブロックを他に割り当てます。私のプロセスに30ヒープがあることは理にかなっていますか?ありがとう。

役に立ちましたか?

解決

私はそれを理解しました - それはコールによって割り当てられるCRTヒープです malloc. 。大量のメモリ(例えば2 MB)を使用して割り当てる場合 malloc, 、それは一つのコミットされたメモリブロックを割り当てます。ただし、小さなチャンク(177kbなど)を割り当てると、1 MBのメモリが予約されますが、おおよそあなたが求めたものだけをコミットします(たとえば、私の177kbリクエストのために184kb)。

その小さなチャンクを解放すると、その大きな1 MBチャンクはOSに返されません。 4K以外のすべてはコミットされていませんが、完全な1 MBはまだ予約されています。あなたが電話した場合 malloc 繰り返しますが、その1 MBチャンクを使用してリクエストを満たそうとします。すでに予約されているというメモリであなたの要求を満たせない場合、それは以前の割り当ての2倍である新しいメモリの一部を割り当てます(私の場合は1 MBから2 MBになりました)。この2倍のパターンが続くかどうかはわかりません。

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

更新:私のテストでは、Heapminはまったく何もしませんでした。 Malloc Heapは、512kb未満のブロックにのみ使用されます。 Malloc Heapに隣接する空きスペースのMBがある場合でも、512kbを超える要求には使用しません。私の場合、この解放された未使用でありながら予約されたマロックメモリは、私のプロセスの大部分を噛み、2GBアドレス空間を噛み、最終的にメモリの割り当て障害につながりました。また、HeapminはメモリをOSに戻していないため、プロセスを再起動したり、自分のメモリマネージャーを書いたりする以外に、この問題の解決策は見つかりませんでした。

他のヒント

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

実際に触れられたコードのみがページに入ります。用語を正しく理解していれば、それがコミットされたときです。

これは、デバッガーでアプリケーションを実行し、ロードされているモジュールを調べて、その場所とサイズをVMMAPで見るものと比較することで確認できます。

アプリケーションでスレッドが作成されるたびに、スレッドのコールスタックのアドレススペースに特定の(構成可能な)メモリが予約されます。スレッドが実際にそのメモリをすべて必要としない限り、すべての予約メモリをコミットする必要はありません。したがって、一部のみをコミットする必要があります。

コミットされた量のメモリが必要な場合、より多くのシステムメモリを取得することが可能になります。

実際の考慮事項は、予約されたメモリが、アプリケーションで利用可能なアドレススペースを削減するスタックサイズの厳しい制限であることです。ただし、保護区の一部のみをコミットすることにより、必要になるまでシステムから同じ量のメモリを消費する必要はありません。

したがって、各スレッドが予約されていないメモリの一部を持つことができます。そのような場合、ページタイプがどうなるか確信が持てません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top