在大量使用unique_ptr语言 - c++后释放内存给操作系统



不知道哪里出了问题。

下面是一个简单的代码

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释放它已分配的内存并将其返回给操作系统?

稍微修改一下代码

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

试着改变这个:

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

:

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

同样,我不会假设知道你打算做什么(或更好地了解),但如果你试图复制的是一个动态分配的双数组,你不需要让它保存unique_ptr,只使用直接的vector<double>。否则,您将为想要存储的每个double创建一个unique_ptr。这是而不是与连续分配的数组相同(因此利用了局部性/缓存)。这似乎会产生不必要的开销。

通常,内存管理器会在需要时向操作系统请求更多内存,但不会在完成后将内存还给操作系统。后者通常很难做到,因为堆使用往往会分散,而且要知道什么时候不再需要操作系统大小的内存块,需要做太多的记录工作。此外,即使内存管理器这样做了,操作系统也可能会把内存分配给你的程序,直到它在其他地方被需要,所以报告内存使用情况的操作系统工具并不能反映你的应用程序实际使用了什么。

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

相关内容

  • 没有找到相关文章

最新更新