2

RTOS から大きなメモリ プールを割り当てます (アプリケーションのメモリ要件は既に​​わかっていますが、特定のサイズを超えて大きくなることはありません)。そして、私のアプリケーション割り当て要求はそのプールから実行されます。

最近、私は問題に直面し始めました。メモリが存在するにもかかわらず、割り当て要求が満たされませんでした (統合されたメモリ ベンチ マーキング フレームワークを取得し、これを示しました)。調査により、メモリの断片化に苦しんでいることが明らかになりました。

私のアプリケーションは、STL (ネットワークからのデータの受信、XML 解析、画像操作、PNG などとしての保存など) に大きく依存しており、メモリ断片化の背後にあるヒープ メモリ割り当て (他の理由はありますか?) を回避するための最良の方法は何ですか?それ?

4

3 に答える 3

4

メモリの断片化の一般的な原因は、プールが古くなるにつれて、大きなメモリ ブロックがますます小さなチャンクに分割されることです。これを回避する簡単な方法は、サイズを固定することです。

これでは、プールが 24MB の場合、各 XML ノードが小さな文字列として格納される XML に 18MB のストレージを使用し、4096 x 4096 x 8 ビットの PNG (16MB) をロードしようとする問題は明らかに解決されません。 XML はメモリを小さなビットに分割するため、16MB の連続したメモリが必要になります。しかし、「固定サイズ」により、XML 文字列が<aaa>b</aaa>4 バイトと 2 バイトのメモリを占有することを回避できます。そのため、4 バイトまたは 2 バイトの長さのオブジェクトは他にないため、そこに格納されている他のものに対してメモリがまったく役に立たなくなります。

この方法では、「固定サイズ」を考慮してメモリ アロケータを作成する必要があります。

于 2013-04-06T08:19:58.187 に答える
2

最初のステップは、RTOS が断片化の少ないヒープのメカニズムを提供しているかどうかを確認することです。

そうでない場合は、他の誰かが断片化の少ないアロケーターを既に実装しているかどうかを確認してください。関連する質問(右側のバーから) は、例を示しています。

第 3 に、他の既存の解決策が機能しない場合、解決策は割り当てに複数のメモリ プールを使用することです。

1 つのプールからのサイズ 1 から X バイトまでの短期間の割り当てと、別のプールからのサイズ 1 から X バイトまでの長期間の割り当てをサービスします。

サイズ X + 1 から 2X、2X +1 から 4X、4X + 1 から 8X などの割り当てについても同様です。(他のバケット サイズを試すこともできます...)

X の最適なサイズを決定するには、アプリをプロファイリングして、各割り当てサイズの頻度を確認する必要があります。

各バケットに割り当てを満たすのに十分なスペースがあることを確認してください:)

于 2013-04-06T08:34:56.417 に答える
0

仮説: ガベージ コレクションに切り替えます。割り当てられたデータを物理的に移動できる圧縮ガベージコレクターが必要です。そうしないと、断片化には役立ちません。

  • ガベージ コレクションは、必ずしもリアルタイム要件と互換性がないわけではありません。リアルタイムとは、「システムが特定の期限内に反応することを保証する必要がある」ことを意味します。ガベージ コレクタが漸進的に動作し、十分に短い「ホールド ザ ワールド」フェーズを保証できる場合は、問題ありません。
  • 最新のガベージ コレクターのパフォーマンスはすべてが悪いわけではありません。人々は常にそれを忘れる傾向がありfreedeleteかなり高価な操作でもあります.
  • ガベージ コレクションにはトレードオフがあります。最も効率的なものは、ホールド ザ ワールド フェーズが長くなります。ホールド・ザ・ワールド・フェーズが短いものは、全体的な効率が低くなります。

残念ながら、これはすべて仮説に過ぎません。現在、C++ の圧縮、インクリメンタル ガベージ コレクターについては知りません。おそらくC++/CLIを除いて。

于 2013-04-06T08:54:14.203 に答える