预先分配的向量向量,但在填充它时仍然线性增加内存
Posted
技术标签:
【中文标题】预先分配的向量向量,但在填充它时仍然线性增加内存【英文标题】:Pre-allocated vector of vectors yet still linear increase of memory while filling it 【发布时间】:2013-09-06 17:46:09 【问题描述】:我很困惑为什么系统监视器显示我的内存在线性增加,因为我在每一行中读取(到同一个变量中),同时将字符串的拆分存储在预分配的内存中。
// pre-allocate
int rows = 100000;
int columns = 300;
QVector<QString> matrix_row;
matrix_row.resize(rows);
QVector< QVector<QString> > matrix;
matrix.resize(num_columns);
qFill(matrix.begin(), matrix.end(), matrix_row);
int current_row = 0;
while(!filestream.atEnd())
QString line = filestream.readLine();
for (int i = 0; i < num_columns; i++)
matrix[i][current_row] = line.left(end[i]).right(grom[i]);
++current_row;
速度是一个问题,所以我在想也许有问题。
初始分配后,它从大约 26% 开始,在我的 8gb 内存的大约 65% 处结束。
可能出了什么问题?
【问题讨论】:
即使您预先分配了向量,当您将文件中的字符串加载到矩阵中时,您仍然会分配更多内存。 @DavidBrown 为什么会这样? 您可以认为QString
类似于专门的QVector<QChar>
。因此,就像QVector
一样,它会为它所保存的数据动态分配内存。因此预分配QVector<QString>
只是为sizeof(QString)
分配空间,这只是指向动态数组的指针和其他一些内务变量的空间。
【参考方案1】:
您必须意识到您的矩阵大小为 100 000 x 300,即它包含 30 000 000 QString
对象
~> 刚构建矩阵后,这些字符串仍然是空的 ~> 当你填充矩阵时,每个新字符串都会额外分配一个小内存块(QString
内部使用),因此内存需求您的应用程序继续增长。
而且由于QVector
是一个复杂的对象,它占用的空间比其元素所需的空间多一点,所以这个小错误也很重要:你resize
行的长度为rows
,而你@ 987654326@ 矩阵的行数等于columns
。它应该是相反的方式。
另请注意,即使在应用上述更改后,此代码:
QVector<QString> matrix_row;
matrix_row.resize(columns);
QVector< QVector<QString> > matrix;
matrix.resize(rows);
qFill(matrix.begin(), matrix.end(), matrix_row);
等价于:
QVector< QVector<QString> > matrix(rows, QVector<QString>(columns) );
【讨论】:
本例中的行列是任意选择的。如果我用第一个元素的 QString 填充矩阵会更好(然后在filestream.seek(0)
之后)?很可能变量的大小不会有太大变化,内存也不应该扩大那么多?
我用我尝试读入的相同字符串完全填充了矩阵,但它仍然会扩展。也许这更像是 Mats Petersson 的情况?【参考方案2】:
在大多数现代操作系统中,如果您分配了相当大的内存块,操作系统只会保留虚拟空间,但只有在您写入内存(或从中读取)后,操作系统才会使用一些物理内存填充它。
此外,向量中的字符串可能占据了大部分空间(除非字符串确实非常小。
【讨论】:
我想这可能是它。这是否意味着预先分配毫无意义,还是有更好的方法来做到这一点?还有,最后一段没看懂? 预分配避免了“增长”,这可能是件好事。但这并不意味着所有的内存都被使用了。第二段试图说“你现在有一个向量或字符串向量,但是所有的字符串都是空的,当你开始往字符串里放东西时,字符串会比空字符串占用更多的内存”。以上是关于预先分配的向量向量,但在填充它时仍然线性增加内存的主要内容,如果未能解决你的问题,请参考以下文章