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

Posted

技术标签:

【中文标题】从文件中读取的数据比文件大小占用更多的内存【英文标题】:Data read from file takes way more memory than file size 【发布时间】:2015-12-12 10:11:28 【问题描述】:

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

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 的内存,然后我收到“在文件 text\qharfbuzzng.cpp,第 626 行:内存不足”错误。 我的问题是:程序开始占用 2 倍以上的文件内存是否正常,我应该分块读取它还是我做错了什么?

【问题讨论】:

【参考方案1】:

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

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

重复直到你读完文件。你会看到你最终得到了(大约)两倍的文件大小。

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

你能切换到 64 位程序吗?这应该可以解决问题。

另一种选择是猜测你有多少元素(根据文件大小)并在开始时在向量上调用.reserve

【讨论】:

感谢您的解释!我会尝试找到一个workarond =) 遗憾的是,保留并没有任何帮助。 在这种情况下,您的选择是:转换为 64 位;分块读取。

以上是关于从文件中读取的数据比文件大小占用更多的内存的主要内容,如果未能解决你的问题,请参考以下文章

“文件夹”-“属性”为啥查看文件大小和占用空间数据是变化的?

虚拟内存设置多少合适?大小主要影响啥?

unity读取图片耗费性能吗

VMware虚拟机Ubuntu里的文件空间占用有问题,请看截图。磁盘上的大小远远大​于文件总大小!!

Redis RDB文件大小size_in_bytes比used_memory_human小

Redis RDB文件大小size_in_bytes比used_memory_human小