3

std::deque を使用したかったのですが、消費されるオーバーヘッド メモリが大きすぎるようです。私は何か間違ったことをしていますか?

#include "windows.h"
#include "psapi.h"

#include <iostream>
#include <vector>
#include <queue>

int main (int, char* [])
{
    PROCESS_MEMORY_COUNTERS pm;
    GetProcessMemoryInfo(GetCurrentProcess(), &pm, sizeof(pm));
    size_t mem1 = pm.WorkingSetSize;

    std::vector<int> v( 10000000 );

    GetProcessMemoryInfo(GetCurrentProcess(), &pm, sizeof(pm));
    size_t mem2 = pm.WorkingSetSize;

    std::deque<int> q( 10000000 );
    GetProcessMemoryInfo(GetCurrentProcess(), &pm, sizeof(pm));
    size_t mem3 = pm.WorkingSetSize;

    std::cout << mem2 - mem1 << std::endl;
    std::cout << mem3 - mem2 << std::endl;

    return 0;
}

出力 (32 ビット Windows システム):

40087552
72564736

おまけの質問: mem2 - mem1 が正確に 40000000 でないのはなぜですか?

4

2 に答える 2

4

両端キューが連続したメモリ ブロックに割り当てられているとは思わない。から ( http://www.cplusplus.com/reference/deque/deque/ ):

vector と deque はどちらも非常によく似たインターフェイスを提供し、同様の目的で使用できますが、内部的にはどちらもまったく異なる方法で機能します。コンテナは必要な情報を内部に保持し、その要素のいずれかに一定時間内に直接アクセスし、統一されたシーケンシャル インターフェイスを提供します。したがって、deque はベクターよりも内部的に少し複雑ですが、これにより、特定の状況下、特に再割り当てがより高価になる非常に長いシーケンスで、より効率的に成長することができます。

于 2013-05-24T20:39:12.580 に答える
2

前に述べたように、adequeはメモリの連続したブロックに割り当てられません。メモリのブロックがどこにあるかを追跡するためにデータを保持する必要があります。詳細は実装に依存しますが、いくつかの詳細は STL 内部で見つけることができます: deque implementation

ワーキング セットは、使用されている物理メモリの量です。ワーキング セットのドキュメントから。

プロセスのワーキング セットは、現在物理メモリに常駐している、プロセスの仮想アドレス空間内のページのセットです。

一部のメモリがディスクにページアウトされている可能性があり、これが不一致を助長しています。

mem2 - mem140000000 と等しくない理由はいくつかあります。単純に、std::vectorオブジェクトに追加のメンバー変数がある可能性があります。サイズ変数と開始イテレータと終了イテレータを追跡できます。もう 1 つの理由は、Windows ヒープもそのメモリを追跡する必要があり、そのためにメモリが必要になることです。

ヒープメモリの管理から

ただし、実際には、ヒープ マネージャーは、ヒープ内のメモリを管理するために追加のメモリを必要とします。そのため、要求に応じて 100 バイトのみを割り当てる代わりに、特定のメモリ チャンクを管理するための領域も割り当てます。メモリの種類と割り当てのサイズによって、この追加メモリのサイズが決まります。

を に置き換えてこれを試すとstd::vector<int>int* v = new int[10000000];メモリの差が 40000000 バイトを超えていることがわかります。

于 2013-05-24T21:02:29.423 に答える