4

私の Windows/C++ アプリケーションは、オペレーターを使用してメモリ内に最大 1Gb のデータを割り当て、newこのデータを処理します。処理後、データは削除されます。

newアプリケーションを終了せずに処理を再度実行すると、オペレーターへの 2 回目の呼び出しで ~1Gb のデータを割り当てることが失敗することに気付きました。

私は、Windows がメモリを返却することを期待しています。これは、他の Win32 呼び出しなどでより適切に管理できますか?

4

5 に答える 5

6

これは Windows の問題ではないと思います。delete または delete[] を正しく使用したかどうかを確認してください。おそらく、メモリを割り当て/解放しているコードを投稿すると役立つでしょう。

于 2008-12-15T11:53:30.247 に答える
5

ほとんどのランタイム環境では、オペレーティング システムからアプリケーションに割り当てられたメモリはアプリケーション内に残り、オペレーティング システムに返されることはめったにありません。メモリ ブロックを解放すると、アプリケーション内からブロックを再利用できますが、オペレーティング システムに対して解放して他のアプリケーションで使用できるようにするわけではありません。

Microsoft の C ランタイム ライブラリは、_heapmin_region に _heap_free_region または _free_partial_region を呼び出して、VirtualFree を呼び出してオペレーティング システムにデータを解放させることにより、メモリをオペレーティング システムに戻そうとします。ただし、対応する領域のページ全体が空でない場合、それらは解放されません。これの一般的な原因は、C++ コンテナーのブックキーピング情報とストレージ キャッシュです。

于 2008-12-15T11:55:00.120 に答える
3

これ、メモリの断片化 (実際にはアドレス空間の断片化) が原因である可能性があります。さまざまな要因が原因で、プログラムのアドレス空間に 1 GB の連続したホールが利用できなくなっています。実際には、メモリ管理のバグが疑われます (申し訳ありません) - リーク検出を使用してコードを実行しましたか?

于 2008-12-15T11:54:48.933 に答える
1

非常に大きなメモリ ブロックを使用しているため、VirtualAlloc()VirtualFree( )の使用を検討する必要があります。これらを使用すると、ヒープ マネージャーとやり取りするオーバーヘッド (メモリと時間) なしでページを直接割り当てて解放できるからです。

C++ を使用しているため、 placement newを使用して、この方法で割り当てたメモリ内に C++ オブジェクトを構築できることに注意してください。

于 2008-12-15T20:22:28.877 に答える
1

この問題は、ほぼ確実にメモリの断片化です。32 ビット Windows では、割り当てることができる最大連続領域は約 1.1GB です (EXE 内のさまざまな DLL が、より大きな連続領域を使用できないため)。メモリ割り当て (または DLL ロード、またはメモリ マップされたファイル) の割り当てを解除した後、以前の 1GB 領域の途中で終了した場合、1GB を割り当てるための次の new の呼び出しに使用できる 1GB 領域がなくなります。したがって、失敗します。

VM Validatorを使用して、このプロセスを視覚化できます。

于 2010-04-10T20:51:02.277 に答える