[解決済み】メモリフラグメンテーションとは何ですか?
質問
C++の動的メモリ割り当ての文脈で、quot;memory fragmentation"という言葉を何度か耳にしたことがあります。 メモリフラグメンテーションにどう対処するかという質問はいくつか見つかりましたが、それ自体を扱う直接的な質問は見当たりません。 そこで
- メモリフラグメンテーションとは何ですか?
- 自分のアプリケーションでメモリの断片化が問題であるかどうかを判断するにはどうしたらよいですか? どのようなプログラムで問題が発生する可能性が高いのでしょうか?
- メモリフラグメンテーションに対処するための一般的な方法は?
また
- ダイナミックアロケーションを多用すると、メモリの断片化が進むと聞いたことがあります。 これは本当でしょうか? C++の文脈では、すべての標準コンテナ(std::string, std::vector など)は動的メモリ割り当てを使用すると理解しています。 これらがプログラム全体で使用されている場合(特にstd::string)、メモリの断片化が問題になる可能性は高いでしょうか?
- STLを多用するアプリケーションでは、メモリの断片化にどのように対処すればよいですか?
どのように解決するのですか?
大きな(32バイト)空きメモリがあると想像してください。
----------------------------------
| |
----------------------------------
では、その一部をアロケートしてください(5回アロケート)。
----------------------------------
|aaaabbccccccddeeee |
----------------------------------
さて、最初の4つのアロケーションを解放しますが、5つ目は解放しないでください。
----------------------------------
| eeee |
----------------------------------
では、16バイトを割り当ててみてください。おっと、その倍近い空き容量があるのに、できませんね。
仮想メモリを使用するシステムでは、断片化は思ったより問題ではありません。 仮想 アドレス空間ではなく 物理的 のアドレス空間です。ですから、この例では、ページサイズ2バイトの仮想メモリがあれば、16バイトの割り当てを問題なく行うことができます。物理メモリは次のようになります。
----------------------------------
|ffffffffffffffeeeeff |
----------------------------------
一方、仮想メモリは(もっと大きいので)次のようになります。
------------------------------------------------------...
| eeeeffffffffffffffff
------------------------------------------------------...
メモリの断片化の典型的な症状は、十分なメモリの空きがあるように見えるのに、大きなブロックを割り当てようとすると割り当てられないというものです。もうひとつ考えられるのは、プロセスがOSにメモリを解放し返せないことです(なぜなら、OSから割り当てた大きなブロックのそれぞれは、たとえば
malloc
などを小分けにするために、各ブロックのほとんどが未使用であるにもかかわらず、何かが残っています)。
C++でメモリの断片化を防ぐ戦術は、サイズや予想される寿命に応じて、異なる領域からオブジェクトを割り当てることで機能します。つまり、たくさんのオブジェクトを作成して、後でまとめて破棄する場合は、メモリプールから割り当てます。オブジェクトとオブジェクトの間にある他のオブジェクトの割り当てはプールから行われないので、メモリ上でオブジェクトとオブジェクトの間に位置することはなく、結果としてメモリは断片化されません。また、同じサイズのオブジェクトをたくさん割り当てるのであれば、同じプールから割り当てます。そうすれば、プール内の空き領域は、そのプールから割り当てようとするサイズより小さくなることはありません。
一般的には、プログラムが長時間動作し、割り当てと解放が大量に行われない限り、あまり気にする必要はないでしょう。最も危険なのは、短命のオブジェクトと長命のオブジェクトが混在している場合ですが、そのような場合でも
malloc
は最善を尽くしてくれます。基本的には、プログラムが割り当てに失敗したり、予期せずシステムのメモリが不足したりするまでは、無視してください (優先順位としては、テスト時にこれをキャッチしてください!)。
標準ライブラリは、メモリ割り当てを行う他のどのようなものよりも悪くありませんし、標準コンテナにはすべて
Alloc
テンプレート・パラメータを使用することで、必要であれば、割り当て戦略を微調整することができます。
関連
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】C++の余分な資格エラー
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] ルール・オブ・スリーとは?
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み】coutはstdのメンバではない
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み】'std::cout'への未定義の参照