0

无法弄清楚发生了什么错误。

这是一个简单的代码

size_t n_elem = 30000000; //careful! will allocate 1GB with unique_ptr
vector<unique_ptr<double> > tmp;
tmp.resize(n_elem);
for(size_t i=0; i<n_elem; i++){
   tmp[i] = unique_ptr<double>(new double((double)i));
}
tmp.clear();
//Some answers in Stack overflow seems to suggest this technique to force
//freeing, but does not seem to work.
vector<unique_ptr<double> > tmp1;
tmp.swap(tmp1);

当这完成时。系统监视器仍然显示 948 MB 已分配,但它应该显示内存使用量激增然后释放所有内容,对吗?即使片段包含在大括号 {...} 中以确保范围,我也看不到任何改进。一旦分配了内存,它似乎直到程序结束才释放。

怀疑带有矢量的东西,我尝试了下面的代码,但行为相同。

{
    size_t n_elem = 30000000;
    unique_ptr<double>* tmp = new unique_ptr<double>[n_elem];
    for(size_t i=0; i<n_elem; i++)
        tmp[i] = unique_ptr<double>(new double((double)i));
    delete[] tmp;
}

然而,

size_t n_elem = 30000000;
double *d_tmp;
d_tmp = new double[n_elem];
for(size_t i=0; i<n_elem; i++)
{
    d_tmp[i] = (double)i;
}
delete[] d_tmp;

此代码显示内存使用量上升到大约 260 MB,然后随着数组被删除而减少。

我尝试使用类而不是双精度类,并计算使用静态变量调用析构函数的次数。在这两种情况下,析构函数都被调用了正确的次数。

我无法弄清楚我使用 unique_ptr 的方式出了什么问题,以及为什么它在销毁后没有返回分配给操作系统的内存。cpp 参考似乎表明这应该在 uniue_ptrs 被破坏时自动发生。如何让 unique_ptr 释放它分配的内存并将其返回给操作系统?

这发生在带有 ubuntu 12.04 和 qtcreator qt 项目的 gcc 4.6 上。

4

3 回答 3

0

通常,内存管理器会在需要时向操作系统请求更多内存,但不要在完成后尝试将其还给操作系统。后者通常很难做到,因为堆的使用往往会飞溅,并且在知道何时不再需要 OS 大小的内存块时涉及到太多的簿记。此外,即使内存管理器这样做,操作系统也可能会将该内存分配给您的程序,直到其他地方需要它为止,因此报告内存使用情况的操作系统工具不会反映您的应用程序实际使用的内容。

这里真正的问题是这种多余的内存是否会产生问题?通常,操作系统通过交换到磁盘来管理大型工作集;未使用的内存块使后备存储混乱,但不要占用 RAM。

于 2013-03-30T13:28:26.773 回答
0

稍微改变你的代码

tmp.clear(); // it is not needed
{
  //Some answers in Stack overflow seems to suggest this technique to force
  //freeing, but does not seem to work.
  vector<unique_ptr<double> > tmp1;
  tmp.swap(tmp1);
}
// measure memory here
于 2013-03-30T05:24:32.403 回答
0

尝试改变这个:

tmp[i] = unique_ptr<double>(new double((double)i));

至:

tmp[i].reset(new double((double)i));

unique_ptr另外,我不会假设知道您打算做什么(或更好地了解),但是如果您要复制的是动态分配的双数组,则无需将其设置为. 直接使用就行了vector<double>。否则,您unique_ptr将为每个double要存储的单曲创建一个。这连续分配的数组不同(因此利用了局部性/缓存)。这似乎会产生不必要的开销。

于 2013-03-30T06:09:04.787 回答