問題タブ [memory-fragmentation]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 自分のメモリマネージャを書く
巨大な動的メモリを割り当てて、それに対して独自のメモリマネージャを作成したいと思います。つまり、コードにメモリが必要な場合は、このメモリプールから割り当てます。内部および外部の断片化をアルゴリズムで処理する必要があります。このための最も効率的なアルゴリズムはどれですか?
c++ - Windows Server 2003 でコミットされていない「プライベート データ」を大量に使用しているのは何ですか?
私はネイティブ C++ アプリケーションを持っており、長期間にわたって多くのことを追跡する必要があります。プロセスが 800 ~ 1200 MB のメモリに達しているとタスク マネージャが示している場合、制限は約 2 GBであるはずですが、メモリが不足しています。
プロセスに対して VMMap を実行したときに何が起こっているのか、ようやく手がかりが得られましたが、それだけでさらに疑問が生じました。私が発見したこと:
- 合計サイズ (タイプ: 合計、列: サイズ) は、タスク マネージャー/プロセス エクスプローラーが報告していたものよりもはるかに大きい
- 合計サイズは、実際には、プログラムがメモリ不足になる前に 2GB を超えることはできない値のようです
- メモリ使用量の不一致は、ほぼ完全に「プライベート データ」が原因です。「コミット」よりも「サイズ」の方がはるかに多くなります。約 800MB のプライベート データがコミットされているケースを見てきましたが、「サイズ」は約 1700MB です。
- 「プライベート データ」の最大のブロックは、主に、「読み取り/書き込み」保護があり、完全にコミットされている 1 つの小さなサブブロック (通常は 4K から 16K の間) と、1 つの大きなサブブロック (4K から 16K の間) のペアのパターンで構成されます。 90K および 400K) には、「予約済み」保護があり、コミットされていません。これは、リソースの膨大な浪費のように思えます。そして、通常、最後に「予約済み」でコミットされていない1つの大きな(数メガバイトの)サブブロックがあります。
- ペアの小さな部分には通常、私が認識できる文字列がありますが、大きなブロックには文字列がまったくありません。
これらのサブブロック ペアの例: (私のアプリケーションではありませんが、考え方は同じです) http://www.flickr.com/photos/95123032@N00/5280550393
プライベート データの 1 つのブロックが完全にコミットされると、新しいブロック (通常、以前の最大のブロックと同じか 2 倍のサイズ) が割り当てられるように見えます。公正に聞こえます。ただし、3 つのブロックがあり、それぞれが 100MB を超えており、コミットされているのは 30MB 未満です。私のアプリケーションは、それが可能なような方法で動作するべきではありません (つまり、400MB を使い切ってから、数時間のうちに 300MB 縮小します)。
私が知る限り、「サイズ」は割り当てられた仮想メモリアドレス空間の実際の量です。「コミット済み」は、実際に使用されている「サイズ」の量です (つまり、new/malloc の呼び出しによって)。それが本当なら、なぜサイズとコミット済みの間にこれほど大きな違いがあるのでしょうか? また、サイズが数百メガバイトのブロックを割り当てているのはなぜですか?
少し奇妙な点は、Windows 7 で実行すると動作がまったく異なることです。2003 Server では、アプリケーションはプライベート データを使用しますが、Windows 7 では、アプリケーションはヒープを使用します。なぜ?VMMap が 2003 では主にプライベート データの使用量を示しているのに、7 では主にヒープの使用量を示しているのはなぜですか? 違いは何ですか?違いの 1 つは、VMMap の [ヒープ割り当て...] ボタンを使用して、すべてのプライベート データがどこに割り当てられているかを確認できないことです。
std::string の過度の使用がこの問題を引き起こしているのではないかと考え始めていました。なぜなら、ペアで認識した文字列 (上記) は主に std::string に格納された文字列で構成されており、頻繁に作成および破棄されていたからです (多くのことを意味します)。メモリの割り当て/割り当て解除)。文字配列を使用するか、メモリ プールのメモリを使用するようにできる限り変換しましたが、効果がないようです。頻繁に新規作成/削除される他のすべてのオブジェクトには、すでに独自のメモリ プールがあります。
断片化ヒープが少ないこともわかったので、それを有効にしてみましたが、やはり違いはありませんでした。Windows 2003 が実際には適切なヒープを使用していないためだと思います。VMMap は、低断片化ヒープが有効になっていることを示していますが、実際には使用されていないため (つまり、代わりにプライベート データを使用しているため)、実際には違いはありません。
実際に起こっているように見えるのは、これらのサブブロックのペアが大きなプライベート データ ブロックを断片化し、OS が新しいブロックを割り当てていることです。最終的に、断片化がひどくなり、コミットされていない領域がたくさんあるにもかかわらず、どれも使用できないように見え、プロセスがメモリ不足になります。
だから私の質問は:
- Windows Server 2003 がヒープではなくプライベート データを使用するのはなぜですか? それは問題ですか?Windows Server 2003 で代わりにヒープ メモリを使用する方法はありますか? もしそうなら、それは私の状況をまったく改善しますか?
- OS のメモリ アロケータによってプライベート データがどのように割り当てられるかを制御する方法はありますか?
- 独自のカスタム ヒープを作成して (コードベースの大部分を変更せずに) 割り当てることは可能ですか? カスタム ヒープを作成できることはわかっていますが、私が知る限り、通常どおり new を呼び出したり、STL コンテナーを使用したりするのではなく、カスタム ヒープから明示的に割り当てる必要があります。
- 私が見逃しているもの、または試してみる価値のあるものはありますか?
c++ - メモリの断片化を回避する方法
RTOS から大きなメモリ プールを割り当てます (アプリケーションのメモリ要件は既にわかっていますが、特定のサイズを超えて大きくなることはありません)。そして、私のアプリケーション割り当て要求はそのプールから実行されます。
最近、私は問題に直面し始めました。メモリが存在するにもかかわらず、割り当て要求が満たされませんでした (統合されたメモリ ベンチ マーキング フレームワークを取得し、これを示しました)。調査により、メモリの断片化に苦しんでいることが明らかになりました。
私のアプリケーションは、STL (ネットワークからのデータの受信、XML 解析、画像操作、PNG などとしての保存など) に大きく依存しており、メモリ断片化の背後にあるヒープ メモリ割り当て (他の理由はありますか?) を回避するための最良の方法は何ですか?それ?
c++ - メモリ断片化の自由を確保するために、短期間のスコープ内でオブジェクトを割り当てるヒープを許可する
私たちは組み込みシステム環境で C++ を使用しており、基本的に動的なメモリ割り当ては必要としません (使用しない理由については、組み込みアプリケーションのメモリ管理に関するリソースなどを参照してください)。それでも、STL コンテナーや std::string などの優れた C++ ベースの機能をいくつか抜きにしてはなりません。最初のものでは、初期化時に特定のサイズを予約し、コンテナーがその容量を超えて大きくならないようにします。後者(std::string)の場合、ヒープにメモリを割り当てることがあるため、「安全に」使用する方法について少し懐疑的でした。
{}
ただし、std::string (および一般的に他のヒープ割り当てオブジェクト) を使用しても問題ないように見える状況を見つけました: オブジェクト自体をスタックに割り当てます (私が話しているように、によって区切られた特定のスコープ内で) C++ から) を使用し、スコープ外に出るときに予約済みメモリを実際にすべて解放することを条件に、ヒープを割り当てることができるようにします。
この方法がメモリの断片化の自由を確実に保証するものではないことは理解していますが、手元のスコープが短命である場合、これは実際にはスコープの終了後に連続した空きメモリになると感じています。
また、複数のタスクが同じヒープを共有しているが、手元のスコープがすべて短命である場合 (たとえば、ブロックしないでください)、最終的に空きメモリが連続している場合に問題が発生する可能性があるのではないかと疑っていました。あるいは、1 つのタスクのみがヒープにメモリを割り当てることを許可され、それが実際に重要な場合は他のタスクが許可されないことは、私には受け入れられます。
ヒープ割り当てオブジェクトの提案された使用法は有効ですか? メモリの断片化を危険にさらすことなく、動的メモリ割り当てを (部分的に) 有効にする別の戦略を誰かが持っていますか?
.net - System.Threading.OverlappedData による多くのメモリの断片化 (非同期待機)
私は常にゆっくりとメモリを使い果たしています。WinDbg を使用してメモリ ダンプを確認したところ、次のようになりました。
断片化されたヒープにはさらに多くのアイテムがあることに注意してください。10MB を超えるアイテムのみを貼り付けました。主な問題は System.Threading.OverlappedData であることがわかります。
最近、すべてのコードを async & await を次のように使用するようにリファクタリングしました。
ソケット インバウンド (ソケット) およびアウトバウンド (Azure サービス バス) 通信が多数あります。このようなメモリの断片化を回避するにはどうすればよいですか?
.net - スレッドのメモリはどのように管理されますか?
.net スレッドは非常に重く、それぞれ約 1MB のメモリを消費することを理解しています (主にスタック用)。さて、これがユーザーの .net クラスである場合、ほとんどのメモリが LOH に置かれる可能性が高いことがわかっています。ただ、コアクラスなので挙動はどうなのか気になります。
この質問の理由は、現在 (潜在的に長寿命の) アプリケーションのメモリ プロファイリングを行っており、遅いリークがあるように思われるためです。VS が 33 個のスレッドを表示していることに気付きました (さまざまな状態で、停止を含む)。スレッドの質素な使用がメモリを断片化する可能性があるのではないかと思います (いくつかの LOH DTO とともに)。
.net - .NET アプリケーションのメモリ使用量 - 未使用の .NET および管理されていないメモリと断片化が多い
ANTS メモリ プロファイラを使用して、.NET 2.0 アプリケーションの 1 つで直面しているメモリ リークの増加を診断しています。私は 7.5 時間にわたってプロセスの 7 つのスナップショットを撮りました。取得したデータを表形式で表したものを次に示します。
G1 は第 1 世代のサイズを表し、G2 は第 2 世代のサイズを表します。アンマネージド スペースとプライベート バイトを除いて、他のすべての値は MB 単位です。
私の質問は -
ヒープ サイズが小さい場合でも、未使用の .NET 領域が大量にあるのはなぜですか?
私の大きなオブジェクト ヒープは最大で約 2 MB になり、最後の 3 つのスナップショットでは 96 KB のままです。では、なぜこのように大きなフラグメントが存在するのでしょうか? また、それらが未使用スペースの原因になっているのでしょうか?
管理されていないスペースは絶えず増加します。それは時間の経過とともにプライベート バイトが増加する原因ですか?
私はこの問題を解決するために機知に富んでおり、いくつかの分析を実行しましたが、これに対する適切な解決策を見つけることができません. 必要なその他のデータを提供する準備ができています。
memory-leaks - メモリ リークとメモリの断片化を区別する
Linux コマンドtop
を使用して実行中のプログラムを観察すると、そのプログラムが使用するメモリが増加していることがわかります。
その症状がメモリリークまたはメモリの断片化によって引き起こされていることをどのように把握するのですか?