预先分配的向量向量,但在填充它时仍然线性增加内存

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&lt;QChar&gt;。因此,就像QVector 一样,它会为它所保存的数据动态分配内存。因此预分配QVector&lt;QString&gt; 只是为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】:

在大多数现代操作系统中,如果您分配了相当大的内存块,操作系统只会保留虚拟空间,但只有在您写入内存(或从中读取)后,操作系统才会使用一些物理内存填充它。

此外,向量中的字符串可能占据了大部分空间(除非字符串确实非常小。

【讨论】:

我想这可能是它。这是否意味着预先分配毫无意义,还是有更好的方法来做到这一点?还有,最后一段没看懂? 预分配避免了“增长”,这可能是件好事。但这并不意味着所有的内存都被使用了。第二段试图说“你现在有一个向量或字符串向量,但是所有的字符串都是空的,当你开始往字符串里放东西时,字符串会比空字符串占用更多的内存”。

以上是关于预先分配的向量向量,但在填充它时仍然线性增加内存的主要内容,如果未能解决你的问题,请参考以下文章

向量组的线性相关性

扩展作为内存传递的向量的大小

机器学习100天(四十):040 线性支持向量机-公式推导

无法将向量转换为字符串

线性代数——向量组的线性相关性

在删除指向动态分配对象的指针向量中的元素之前,我需要做啥?