从文件中读取的数据占用的内存远远多于文件大小

Data read from file takes way more memory than file size

本文关键字:内存 文件大小 文件 读取 数据      更新时间:2023-10-16

我以以下方式将一些数据写入文件:

result = new QHash<QPair<int, int>, QVector<double> >;
QFile resfile("result.txt");
resfile.open(QIODevice::WriteOnly | QIODevice::Append);
QDataStream out(&resfile);
while(condition)
{
QString s=" something";
out<<s;
res->insert(QPair<int, int>(arange,trange),coeffs);
out<<res;
}

该文件最终的大小为484MB。在那之后,我循环阅读:

QString s;
QVector<QHash<QPair<int, int>, QVector <double> > >    thickeness_result;
QFile resfile("result.txt");
resfile.open(QIODevice::ReadOnly);
QDataStream out(&resfile);
while (!out.atEnd())
{
 thickeness_result.resize(thickeness_result.size()+1);
out>>s>>thickness_result.last();   
 }

当这个读取循环运行时,我看到在任务管理器中,我的程序开始占用大约1300MB的内存,之后我收到一个"in file text\qharfbuzzng.cpp,line 626:Out of memory"错误。我的问题是:程序开始占用超过2倍大小的文件内存,我应该分块读取它,这正常吗?还是我做错了什么?

警告以下所有假设QVector的行为与std::vector 类似

是的,这很正常。实际情况是,当您有1024个元素,并且想要读取另一个元素时,对resize的调用是为2048个元素分配容量,将前1024个元素移入,然后构造第1025个元素。它销毁旧数组,并将内存返回堆(但不返回操作系统)。然后,当您开始读取2049个元素时,它会再次执行所有操作,只是这次分配了4096个元素。堆有一个1024个元素的块空间,但当您想要4096个元素时,这是没有用的。现在,堆中有1024、2048和4096个元素块(其中两个是免费的,可以重用)。

重复此操作,直到您读取了文件。你会看到你最终得到的文件大小(大约)是原来的两倍。

第一条规则是"不要担心"——这通常不是问题。然而,对你来说,这显然是。

你能切换到64位程序吗?这应该会让问题消失。

另一个选项是(根据文件大小)猜测有多少元素,并在开始时对向量调用.reserve