ノードのミリオインの情報を含む大量のストリーミングデータを処理するC++で書いています。ベクトルを使用して、各ノードの名前とインデックス用のマップを保存します。
ここで問題となるのは、ベクトルが予想よりもはるかに多くのメモリを使用しており、それらの破壊が説明できないことです。
somefileに100万行が含まれ、各行が50文字を超えるとします。それらを2回読み込んでから、プロセスのメモリ使用量とベクトルによる推定メモリ使用量を確認します。それらは60MBで異なります。これは私が抱えているより大きな問題のほんの小さな予測であり、GBスケールが異なる場合があります。
Windows7 SP1 Ultimate64ビットでVS2010SP1を使用して、x86設定でプログラムをコンパイルします。
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <Windows.h>
#include <Psapi.h>
using namespace std;
//#define COUNT 500000
int COUNT = 0;
vector<string> namesVector;
map<string,int> namesMap;
void ProcessStatistics()
{
PROCESS_MEMORY_COUNTERS memCounter;
GetProcessMemoryInfo(GetCurrentProcess(),&memCounter,sizeof(memCounter));
cout<<"Mem Usage by Process: "<<memCounter.WorkingSetSize * 1.0e-6f<<" MB."<<endl;
}
void VectorMemUsage()
{
COUNT = namesVector.size();
int overhead = StringOverhead();
double mem = 0;
mem += sizeof(vector<string>);
mem += overhead*COUNT;
for(int i=0; i<COUNT; i++)
{
mem += namesVector[i].capacity();
}
cout<<"Calculated String Vector Usage: "<<mem * 1.0e-6f<<" MB of "<<COUNT<<" strings."<<endl;
}
int StringOverhead()
{
int overhead = sizeof(string);
cout<<"String overhead: "<<overhead<<" Bytes."<<endl;
return overhead;
}
void main(){
const std::string infile = "somefile";
ifstream infstream(infile);
string s;
while(getline(infstream,s) != NULL)
{
namesVector.push_back(s);
//namesMap.insert(pair<string,int>(s,namesVector.size()));
}
infstream.clear();
infstream.seekg(0,ios::beg);
while(getline(infstream,s) != NULL)
{
namesVector.push_back(s);
//namesMap.insert(pair<string,int>(s,namesVector.size()));
}
//Check process and vector memory usage:
ProcessStatistics();
VectorMemUsage();
System("pause");
//Release the vector.
cout<<"Now releasing the memory..."<<endl;
//vector<string>(namesVector).swap(namesVector);
//vector<string>().swap(namesVector); //Deallocate Vector
//map<string,int>().swap(namesMap); //Deallocate Map
cout<<"Capacity of vector "<<namesVector.capacity()<<endl;
ProcessStatistics();
}
プログラム出力のx86バージョンは次のようになります。
Mem Usage by Process: 336.523 MB.
String overhead: 28 Bytes.
Calculated String Vector Usage: 301.599 MB of 3385108 strings.
Press any key to continue . . .
Now releasing the memory...
Mem Usage by Process: 7.64314 MB.
vectorでnamesVector.shrink_to_fit()またはvector(namesVector).swap(namesVector)イディオムを呼び出すと、ベクトル容量は実際に減少しますが、メモリ使用量が高くなりました。これを修正するアイデアはありますか?スワップトリックはポインタスワップであると想定されていますか?なぜそれはメモリコピーとすべてを含み、これを引き起こすのでしょうか?
Mem Usage by Process: 336.536 MB.
String overhead: 28 Bytes.
Calculated String Usage: 301.599 MB of 3385108 strings.
Vector Capacity is 3543306.
Calculated String Vector Usage: 315.693 MB of 3385108 strings.
Now releasing the memory...
Capacity of vector 3385108
Mem Usage by Process: 434.5 MB.
文字列インデックスのマップを追加すると、予期しない動作が発生しました。vector()。swap(namesVector)とmap()。swap(namesMap)の両方を呼び出すと、結果は次のようになります。これは、メモリが解放されるため、かなり問題ありません。
Mem Usage by Process: 534.778 MB.
String overhead: 28 Bytes.
Calculated String Usage: 301.599 MB of 3385108 strings.
Vector Capacity is 3543306.
Calculated String Vector Usage: 315.693 MB of 3385108 strings.
Press any key to continue . . .
Now releasing the memory...
Capacity of vector 0
Mem Usage by Process: 8.2903 MB.
しかし、vector()。swap(namesVector)のみを呼び出すと、メモリが部分的に解放されます。部分的には、上記の結果(約336 MB)よりもリリースが少ないことを意味します。
Mem Usage by Process: **534.77** MB.
String overhead: 28 Bytes.
Calculated String Usage: 301.599 MB of 3385108 strings.
Vector Capacity is 3543306.
Calculated String Vector Usage: 315.693 MB of 3385108 strings.
Press any key to continue . . .
Now releasing the memory...
Capacity of vector 0
Mem Usage by Process: **440.459** MB.
またはmap()。swap(namesMap)の場合、メモリはほとんど解放されません。
Mem Usage by Process: **534.774** MB.
String overhead: 28 Bytes.
Calculated String Usage: 301.599 MB of 3385108 strings.
Vector Capacity is 3543306.
Calculated String Vector Usage: 315.693 MB of 3385108 strings.
Press any key to continue . . .
Now releasing the memory...
Capacity of vector 3543306
Mem Usage by Process: **535.441** MB.
何が起こったのか説明できません。ここで何が起こったのか誰にも分かりますか?
助けてくれてありがとう。
一番。