リンクされたオブジェクトの動的メモリをクリーンアップする必要があります。最適化問題の分岐限定アルゴリズムを研究しています。部分解のデータを保持する「ノード」というクラスがあります。「new」関数を使用してノードを作成します。作成されたすべてのノードは、マヌエル リストを作成したように、互いにリンクされてチェーンを形成します。各ノードは、その後に続く最適なノードの物理アドレスを認識しています。このチェーンは動的です。既存のノードを使用して新しいノードを生成し、最適なソリューションが見つかるまでチェーンにリンクします。一部の問題については、ノード数が約 30 億 (30 ~ 40 GB) のときに最適なソリューションを見つけました。1 つの問題を解決し終わったら、次の問題を解決するためにコードを渡すように設定します (これは、プロセス中に複数のファイル ストリーミングによって行います)。別の問題を解決するために、渡す前にメモリを解放する必要があります。最適なものが見つかり、ノードチェーンが不要になったときに「削除」機能を使用しようとしました。悪いことに、相互にリンクされた 30 億のノード オブジェクトを削除するには数時間かかります。プログラムを終了し、解決済みのファイルをディレクトリから削除し、ウィンドウが RAM を解放するのを待ってから、もう一度再起動して作業を続けます。終了プロセスが行うクリーニング操作のように、解決する別の問題に渡しながらメモリを解放する方法はありますか、またはノードチェーンの構造を変更する必要がありますか? 解決済みのファイルをディレクトリから削除し、ウィンドウがRAMを解放するのを待ってから、もう一度再起動して作業を続けます。終了プロセスが行うクリーニング操作のように、解決する別の問題に渡しながらメモリを解放する方法はありますか、またはノードチェーンの構造を変更する必要がありますか? 解決済みのファイルをディレクトリから削除し、ウィンドウが RAM を解放するのを待ってから、もう一度再起動して作業を続けます。終了プロセスが行うクリーニング操作のように、解決する別の問題に渡しながらメモリを解放する方法はありますか、またはノードチェーンの構造を変更する必要がありますか?
3 に答える
割り当てを解除できるプールから割り当てる、カスタマイズされた新しい仕事のように聞こえます。
class Node
{
void* operator new(size_t bytes);
void delete(void* ptr) {}
...
};
これで、新しいオペレーターがこれを実行できます
char* big_block = new char[100000];
char* free_ptr = big_block;
void* Node::operator new(size_t bytes)
{
char* ptr = free_ptr;
free_ptr += bytes;
return ptr;
}
その後、完了したら、電話をかけるだけでdelete[] big_block;
、すべてのメモリが解放されます。とにかくそのようなもの。追加する詳細がいくつかあります。
30億個のオブジェクトがある場合、30億個のオブジェクトを解放する必要があります。ただし、ごまかす場合は除きます。
すでに正しく指摘しているように、不正行為の1つの方法はプロセスを強制終了することです。もちろん、それは後で何か他のことをすることを除外します。
もう1つの方法は、オーバーロードoperator new
してブロックアロケータを使用し、operator delete
何もしない(またはすべて忘れるoperator delete
)ことです。ブロックアロケータは、割り当てたオブジェクトが描画されている1つの巨大なブロック(または、必要に応じて複数のブロック、リンクリストに含まれている可能性があります)を割り当てます。これは、比較的簡単な方法で実装できます(配列から要素を返し、インデックスをインクリメントします)。
次に、30億個のオブジェクトを使い終わったら、ブロックアロケータで、一度にブロック全体を破棄する(割り当てを解除する)関数を呼び出します。アロケータは30億個のオブジェクトについて知らず、気にしません。それが行うのは、1つ(またはおそらく3〜4)の大規模な割り当て解除だけです。
デストラクタを使用して、コンストラクタによって割り当てられたリソース、またはミューテータによって割り当てられた追加のリソースを解放します。