1

ここでは少し奇妙なシナリオを扱っていますが、これはまさに私が作成しようとしていたものです。それは特別な種類のテストソフトウェアです...

私の環境: MSVS 2012、Windows 7/8 32b/64b。

したがって、最初にアプリで使用する内部構造/バッファ/などをいくつか作成してから、次のようなことを行っています (ここでは少し簡略化しています。疑似コードのように扱ってください)。

{
   std::deque<boost::scoped_array<unsigned char>> deque;
   try {
     while (1) {
       deque.push_back(boost::scoped_array<unsigned char>(new unsigned char[system_page_size])); // happens to be 4096 on my system
     }
   }
   catch (std::bad_alloc& ex) { ... }
   // do something here
}

できるだけ多くのメモリを使用する必要があります。ページ全体を一度に割り当てています (おそらくそれは悪いことであり、deque の/smart ptr のデータ用にいくらかのスペースを残す必要がありますか?)。CRT がこれ以上の割り当てが不可能であると判断した場合、(メモリの可用性にまったく依存せずに) さらにいくつかのことを行い、スコープを終了します。デストラクタのチェーンをトリガーし、このすべてのデータを解放する必要があります。

これはうまくいきます。しかし、私はたまたまこの奇妙なスコープに一度ではなく、ループで 10 回入りました。2~3回でうまくいくこともあります。時には一度だけ。次回はメモリ不足エラーのみが発生します。それだけです。

私の観点からは、メモリを強制的に解放するには、プロセス全体を再起動する必要があります。単一のプロセスでこれを達成する方法はありますか?

別のアロケーターを試すことを考えることができます-多分それはCRTの問題ですか? また、ヒープ操作 (つまり、断片化の少ないヒープ) も少し試しましたが、どちらも役に立ちませんでした。

4

2 に答える 2

0

MEM_RESERVEを使用して、いくつかの大きなサイズのVirtualAlloc呼び出しで、プロセスのメモリスペース全体を予約してみませんか。次に、後で各メモリ範囲でVirtualFreeを呼び出して解放します。これでも、現在のヒープの残りを使い果たすためにここで行っているように、ある程度のヒープ割り当てが必要になります。それはより速くなり、あなたが経験しているに違いないページファイルチャーンを取り除きます。

あなたの具体的な問題については、なぜあなたがそれを経験しているのか分かりません。ヒープが拡張できないようにすべてのメモリを予約すると、非決定論を減らすのに役立ちます。

于 2012-12-28T23:17:49.083 に答える
0

大量のメモリを使用している場合は、ある種のスラブ割り当てを使用し(VirtualAllocはそのためのメモリを提供します)、原則として[そのブロックで作成されたオブジェクトが何かを行うためにデストラクタを必要としないと仮定します] 、何億回も削除を使用するのではなく、ブロック全体を一度に破棄することができます。時間の節約と、メモリが完全に解放されたことを保証するという追加の利点があります。

問題が発生する理由の1つは、解放されたブロックをリサイクルする前にクリアする必要があることだと思います。これは、カーネルのバックグラウンドスレッドで実行されます。もちろん、VirtualALlocを使用しても、このアカウントでは実際には役に立ちません。

もちろん、メモリの断片化が発生する可能性もあります。その場合、これを回避するように設計されたヘッドを使用すると機能します。

于 2012-12-28T23:29:01.687 に答える