c ++が割り当てているメモリの量を理解する

ジオ:

私はc ++でヒープに割り当てられているメモリの量をよりよく理解しようとしています。基本的に、いくつかの2Dベクトルを埋める以外に何もしない小さなテストプログラムを作成しました。私はこれをLinux 64ビットVMで実行しており、メモリのプロファイルを作成するためにvalgrindのMassifツールを使用しています。

このテストを実行している環境:Win10のVirtualBoxで実行されているLinux VM。VM構成:ベースメモリ:5248MB、4CPU、上限100%、ディスクタイプVDI(動的に割り当てられたストレージ)。

c ++メモリプロファイリングテストプログラム:

/**
 * g++ -std=c++11 test.cpp -o test.o
 */

#include <string>
#include <vector>
#include <iostream>

using namespace std;

int main(int argc, char **arg) {
    int n = stoi(arg[1]);
    vector<vector<int> > matrix1(n);
    vector<vector<int> > matrix2(n);
    vector<vector<int> > matrix3(n);
    vector<vector<int> > matrix4(n);
    vector<vector<int> > matrix5(n);
    vector<vector<int> > matrix6(n);
    vector<vector<int> > matrix7(n);
    vector<vector<int> > matrix8(n);

    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            matrix1[i].push_back(j);
        }
    }

    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            matrix2[i].push_back(j);
        }
    }

    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            matrix3[i].push_back(j);
        }
    }

    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            matrix4[i].push_back(j);
        }
    }

    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            matrix5[i].push_back(j);
        }
    }

    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            matrix6[i].push_back(j);
        }
    }

    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            matrix7[i].push_back(j);
        }
    }

    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            matrix8[i].push_back(j);
        }
    }
}

の異なる値でメモリプロファイルを抽出するために次のbashスクリプトを実行しますn(test.oは上記のプログラムで、g ++ -std = c ++ 11でコンパイルされています。g++はバージョン5.3.0です)

valgrind --tool=massif --massif-out-file=massif-n1000.txt ./test.o 250
valgrind --tool=massif --massif-out-file=massif-n1000.txt ./test.o 500
valgrind --tool=massif --massif-out-file=massif-n1000.txt ./test.o 1000
valgrind --tool=massif --massif-out-file=massif-n2000.txt ./test.o 2000
valgrind --tool=massif --massif-out-file=massif-n4000.txt ./test.o 4000
valgrind --tool=massif --massif-out-file=massif-n8000.txt ./test.o 8000
valgrind --tool=massif --massif-out-file=massif-n16000.txt ./test.o 16000
valgrind --tool=massif --massif-out-file=massif-n32000.txt ./test.o 32000

これにより、次の結果が得られます。

|--------------------------------|
| n     | peak heap memory usage |
|-------|------------------------|
| 250   | 2.1 MiB                |         
| 500   | 7.9 MiB                |
| 1000  | 31.2 MiB               |
| 2000  | 124.8 MiB              |
| 4000  | 496.5 MiB              |
| 8000  | 1.9  GiB               |
| 16000 | 6.2 GiB                |
| 32000 | 6.1 GiB                |
|--------------------------------|

各行列のサイズはn ^ 2になります。合計8つの行列があるため、メモリ使用量はと予想されましたf(n) = 8 * n^2

質問1 n = 250からn = 8000まで、n * = 2でメモリ使用量が4倍になるのはなぜですか?

n = 16000からn = 32000までは、valgrindが実際にメモリの減少を報告するため、非常に奇妙なことが起こっています。

質問2 n = 16000とn = 32000の間で何が起こっていますか。理論的にはより多くのデータを割り当てる必要があるのに、ヒープメモリが少なくなる可能性はありますか

以下のn = 16000およびn = 32000のmassif-visualizer出力を参照してください。

n = 16000 n = 32000

meowgoesthedog:

1)行列ベクトルのサイズ(およびそのメモリフットプリント)がn 2として増加するため、nを2倍にすると、メモリ使用量が4倍になります。漸近的なものとは対照的に正確な関係からの逸脱は、さまざまな要因によるものです(たとえばmalloc / std::allocatorによって使用されるメタデータによって使用されるブロックサイズ倍加方法vector

2)メモリが不足し始めているため、Linuxがページングを開始しています(アクティブ+ページングされた)合計メモリ使用量--pages-as-heap=yesを確認する場合に使用します。(出典:http : //valgrind.org/docs/manual/ms-manual.html

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

cのメモリ割り当てとポインタを理解する

分類Dev

C ++のベクトルがメモリを割り当てる方法

分類Dev

Cですでに割り当てられているメモリ内のメモリ割り当て

分類Dev

C ++で配列にメモリを割り当てるのはいつですか?

分類Dev

Cの配列要素に割り当てられたメモリアドレスを理解する(Windows 10ではgcc)

分類Dev

Cのポインタ:値を割り当ててメモリを割り当てるVS値を割り当てずにメモリを割り当てる

分類Dev

Cプログラムでメモリが割り当てられて使用されるのはいつですか?

分類Dev

c-メモリアドレスが割り当てられているかどうかを確認します

分類Dev

なぜc / c ++でメモリを割り当てる必要があるのですか?

分類Dev

Cでのメモリ割り当てに関するいくつかの質問

分類Dev

C ++でのメモリの割り当て解除に関する混乱

分類Dev

cの文字列の配列にメモリを割り当てる

分類Dev

C ++でメモリが実際に新しいint [250000000]に割り当てられるのはいつですか。

分類Dev

Cでの特定のタイプのメモリ割り当てを解放する

分類Dev

Cのメモリ位置に新しい値を割り当てる方法

分類Dev

Cのメモリ位置に新しい値を割り当てる方法

分類Dev

cの変数にメモリが割り当てられるのはいつですか?

分類Dev

Cでのメモリ割り当てに関する質問

分類Dev

Cでのメモリ割り当てに関する問題

分類Dev

Cでメモリの割り当てを解除する必要は何ですか?

分類Dev

Cでメモリ割り当てを処理する方法

分類Dev

Cで割り当てられたメモリを解放する

分類Dev

C ++でメモリの割り当てを解除する際のイテレータとポインタの違い

分類Dev

外部に割り当てられたメモリを参照するcの機能

分類Dev

C#でforeachループを使用する場合のメモリ割り当て

分類Dev

すでに割り当てられているメモリを指すC ++ベクトルを作成する

分類Dev

C ++でメモリの割り当てを解除するのを忘れるとどうなりますか

分類Dev

cでの動的メモリ割り当て、malloc()を使用する前に割り当てられたメモリの一部を解放します

分類Dev

mallocを使用してCの文字列にメモリを割り当てる

Related 関連記事

  1. 1

    cのメモリ割り当てとポインタを理解する

  2. 2

    C ++のベクトルがメモリを割り当てる方法

  3. 3

    Cですでに割り当てられているメモリ内のメモリ割り当て

  4. 4

    C ++で配列にメモリを割り当てるのはいつですか?

  5. 5

    Cの配列要素に割り当てられたメモリアドレスを理解する(Windows 10ではgcc)

  6. 6

    Cのポインタ:値を割り当ててメモリを割り当てるVS値を割り当てずにメモリを割り当てる

  7. 7

    Cプログラムでメモリが割り当てられて使用されるのはいつですか?

  8. 8

    c-メモリアドレスが割り当てられているかどうかを確認します

  9. 9

    なぜc / c ++でメモリを割り当てる必要があるのですか?

  10. 10

    Cでのメモリ割り当てに関するいくつかの質問

  11. 11

    C ++でのメモリの割り当て解除に関する混乱

  12. 12

    cの文字列の配列にメモリを割り当てる

  13. 13

    C ++でメモリが実際に新しいint [250000000]に割り当てられるのはいつですか。

  14. 14

    Cでの特定のタイプのメモリ割り当てを解放する

  15. 15

    Cのメモリ位置に新しい値を割り当てる方法

  16. 16

    Cのメモリ位置に新しい値を割り当てる方法

  17. 17

    cの変数にメモリが割り当てられるのはいつですか?

  18. 18

    Cでのメモリ割り当てに関する質問

  19. 19

    Cでのメモリ割り当てに関する問題

  20. 20

    Cでメモリの割り当てを解除する必要は何ですか?

  21. 21

    Cでメモリ割り当てを処理する方法

  22. 22

    Cで割り当てられたメモリを解放する

  23. 23

    C ++でメモリの割り当てを解除する際のイテレータとポインタの違い

  24. 24

    外部に割り当てられたメモリを参照するcの機能

  25. 25

    C#でforeachループを使用する場合のメモリ割り当て

  26. 26

    すでに割り当てられているメモリを指すC ++ベクトルを作成する

  27. 27

    C ++でメモリの割り当てを解除するのを忘れるとどうなりますか

  28. 28

    cでの動的メモリ割り当て、malloc()を使用する前に割り当てられたメモリの一部を解放します

  29. 29

    mallocを使用してCの文字列にメモリを割り当てる

ホットタグ

アーカイブ