c++ - 如何确保 std::vector 分配的内存在解除分配后返回给操作系统?

标签 c++ memory stl operating-system glibc

下面的代码正在调用 foo 并使用 while(1) 来观察内存使用情况。据我所知,在打印“完成”后,var d 被释放,STL 容器将自行释放数据空间(堆)。

#include <vector>
#include <string>
#include <iostream>

void foo() {
  std::vector<std::string> d(100000000);
  for(int i = 0; i < 100000000; ++i) d[i] = "1,1,3";
  d.resize(0);
  d.shrink_to_fit();
}

int main(int argc, char *argv[])
{
  foo();
  std::cout << "finished" << std::endl;
  while(1) {;}
  return 0; 
}

但我观察到的(使用 htop):内存没有释放回操作系统。这只是一个工作台和与 MESOS 相关的真实代码,每个进程都有内存限制。

我在使用 glibc 2.15 的 linux 服务器上尝试了几个版本的编译器,例如 g++-4.7.2 g++-4.8.1、clang++。此外,我还使用了 tcmalloc 而不是默认的 malloc,但它仍然不起作用(在 MAC 机器上不会发生该问题)。

有什么问题?我怎样才能确保内存返回给操作系统? 谢谢。

最佳答案

How can I make sure the memory give back to os?

您可以终止您的进程。

What's the problem?

可能没有。程序不返回内存是正常的(尽管 Linux 确实会为一些特别大的分配提前返回内存)。他们通常使用 sbrk 或等价物来增加他们可用的虚拟地址空间,但通常不值得尝试返回已释放的内存。这可能是违反直觉的,但它也被证明在几十年的数百万个程序中是可行的,所以除非你有具体的切实问题,否则你不应该为它烦恼。它不应该给你带来问题,因为当应用程序执行进一步分配时,释放的内存将被重用,所以你提到的“每个进程的 MESOS 内存限制”仍然以相同的方式影响最大瞬时内存使用的“高水位线”。

请注意带有 virtual memory 的操作系统支持可能会将长时间未使用的已释放页面交换到磁盘,以便内核或其他应用程序重用后备 RAM

也可以使用例如手动控制。内存映射文件,但是编写这样的分配器并使用标准容器是一项非常重要的工作......关于如何解决该问题的许多其他 SO 问题。

关于c++ - 如何确保 std::vector 分配的内存在解除分配后返回给操作系统?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27140658/

相关文章:

c++ - 如何在最多进行 3N 次比较时实现 std::make_heap ?

c++ - 如何使用const_reference类型声明变量并赋值给它,即front()函数的返回值

c++ - 将输出重定向到文件,然后返回到C++中的控制台

c++ - fstream EOF 意外抛出异常

c++ - QVector<float> 或 float* - Qt 内存管理优于 native C++?

c++ - 两个函数局部变量的内存冲突

c++ - 使用 shared_ptr,安全吗?

C++ exec 执行的 bash 脚本随机停止

c# - 在另一个线程中使用线程时发生内存泄漏

c++ - 使用 shared_ptrs 的 pair<unsigned int, boost::any> 类型的通用容器的线程安全实现