5

私たちは組み込みシステム環境で C++ を使用しており、基本的に動的なメモリ割り当ては必要としません (使用しない理由については、組み込みアプリケーションのメモリ管理に関するリソースなどを参照してください)。それでも、STL コンテナーや std::string などの優れた C++ ベースの機能をいくつか抜きにしてはなりません。最初のものでは、初期化時に特定のサイズを予約し、コンテナーがその容量を超えて大きくならないようにします。後者(std::string)の場合、ヒープにメモリを割り当てることがあるため、「安全に」使用する方法について少し懐疑的でした。

{}ただし、std::string (および一般的に他のヒープ割り当てオブジェクト) を使用しても問題ないように見える状況を見つけました: オブジェクト自体をスタックに割り当てます (私が話しているように、によって区切られた特定のスコープ内で) C++ から) を使用し、スコープ外に出るときに予約済みメモリを実際にすべて解放することを条件に、ヒープを割り当てることができるようにします。

この方法がメモリの断片化の自由を確実に保証するものではないことは理解していますが、手元のスコープが短命である場合、これは実際にはスコープの終了後に連続した空きメモリになると感じています。

また、複数のタスクが同じヒープを共有しているが、手元のスコープがすべて短命である場合 (たとえば、ブロックしないでください)、最終的に空きメモリが連続している場合に問題が発生する可能性があるのではないかと疑っていました。あるいは、1 つのタスクのみがヒープにメモリを割り当てることを許可され、それが実際に重要な場合は他のタスクが許可されないことは、私には受け入れられます。

ヒープ割り当てオブジェクトの提案された使用法は有効ですか? メモリの断片化を危険にさらすことなく、動的メモリ割り当てを (部分的に) 有効にする別の戦略を誰かが持っていますか?

4

2 に答える 2

6

過去に、タイトな組み込みシステムであらゆる種類の C++ スタイルの動的メモリ割り当てを行ってきました。いくつかのルールに従い、短期バッファーと長期バッファーの混在に注意する必要があります。まず、記事にあるように、メモリ プールはあなたの味方です。

また、ペアおよび制御構造を支援するために C++ が好んで行うすべての小さい (<64 バイト) 割り当てでは、断片化制御だけでなく、パフォーマンスのためにも、ユニット割り当てスキームが不可欠です。ユニット アロケータは、同じサイズのメモリ ユニット (たとえば 64 バイト) を事前に割り当て、空きスタックに配置します。メモリが割り当てられると、それらを空きスタックからポップして返します。すべてのサイズが同一であるため、ブロック サイズに対する内部断片化のみが発生します。完了時にメモリに参加する必要がないため、割り当てと解放は O(1) 時間です。

その他のルール: 長期間有効な動的割り当てを行う必要がある場合は、その前に短期間の割り当てを行わないでください。最初に大きなバッファを割り当て、次に小さなバッファを割り当てて、メモリが分散しないようにします。別のシステムでは、ヒープの後ろに長期の割り当てを配置し、前に短期の割り当てを配置します。私たちもそれで成功しました。

複数のヒープ (プール) を使用して、さまざまな種類の割り当てを分離することもできます。コードの 1 つのセクションで大量の短期的な割り当てを作成しているものがあり、別のセクションが別のパターンに従っている場合は、それらに別のヒープを与えます。

上記のすべてに注意して従えば、断片化を防止または制限できます。別の解決策は、再配置可能なメモリ割り当てシステムを使用することです。このシステムでは、優先度の低いスレッドがメモリを並べ替えて、時間の経過とともに連続した状態を維持できます。私はそれが数回行われたことも見てきました.0の長期的な断片化のために少しのパフォーマンスを引き換えに.

allocaも役立ちますが、メモリの断片化を防ぐ方法に従っていない場合は、スタックも散らばってしまうだけです。また、これは埋め込まれた土地ではより価値のあるリソースになる傾向があるため、これは良い考えではないかもしれません.

于 2013-05-06T15:36:41.550 に答える