【发布时间】:2016-01-22 13:12:41
【问题描述】:
有些东西我不明白,非常感谢您的澄清。我知道有很多关于 std::containers 和未释放内存的问题,但我仍然不了解一个特定的事实。
下面是一个最小程序,它代表了我在生产系统中遇到的问题。在 cmets 中,在 Ubuntu 上等待 std::cin 时会从 /proc/PROC_NUM/status 读取内存消耗。问题也在 cmets 中。
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <vector>
class MyObject
{
public:
MyObject(int r=1000)
: array(new float[r])
{
for (int i = 0; i<r;i++)
{
array[i] = random();
}
}
~MyObject()
{
delete[] array;
}
public:
float* array;
};
int main(int argc,char*argv[])
{
char a;
const int count=100;
std::cout<<"Start after input"<<std::endl;
std::cin >> a;
// VmSize: 12704 kB
{
std::vector<MyObject*> vec;
for(int i=0; i<count; i++)
{
vec.push_back(new MyObject);
}
std::cout<<"Release after input"<<std::endl;
std::cin >> a;
// VmSize: 13100 kB, alright, MyObjects fill around 400kB (what I expected)
for (int i=0; i<count; i++)
{
delete vec[i];
vec[i]=NULL;
}
std::cout<<"Run out of scope of vector after input"<<std::endl;
std::cin >> a;
// VmSize: 13096 kB, Why are the 400k not freed yet?
}
std::cout<<"Shutdown after input"<<std::endl;
std::cin >> a;
// VmSize: 12704 kB, Why are now around 400k freed? The only thing that is freed here is the vector of pointers.
return 0;
}
如果我改为使用 MyObjects 数组,则在删除它后会立即释放内存:
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <vector>
class MyObject
{
public:
MyObject(int r=1000)
: array(new float[r])
{
for (int i = 0; i<r;i++)
{
array[i] = random();
}
}
~MyObject()
{
delete[] array;
}
public:
float* array;
};
int main(int argc,char*argv[])
{
char a;
const int count=100;
std::cout<<"Start after input"<<std::endl;
std::cin >> a;
// VmSize: 12700 kB
{
MyObject* vec(new MyObject[count]);
std::cout<<"Release after input"<<std::endl;
std::cin >> a;
// VmSize: 13096 kB, alright, around 400k again
delete[] vec;
std::cout<<"Run out of scope of vector after input"<<std::endl;
std::cin >> a;
// VmSize: 12700 kB, 400k freed again, perfect.
}
std::cout<<"Shutdown after input"<<std::endl;
std::cin >> a;
// VmSize: 12700 kB, nothing changed, as expected
return 0;
}
我读到的答案告诉我不能相信操作系统的内存号(目前我在 Linux 上使用了 /prop/PROC_NO/status 的输出)。我可以用什么来监控内存消耗?我在 XCode Instruments 的 Mac 上尝试了同样的方法,我什至没有这个问题。意味着第一种情况下的内存消耗等于第二种情况。
在 Ubuntu 上,我尝试了不同版本的 gcc 和 clang,它们都表现出相同的行为。
在我的生产系统中,有一个 std::map 而不是一个 std::vector,但问题是一样的。
【问题讨论】:
-
您可以使用具有跟踪/调试支持的自定义分配器来更准确地了解内存消耗情况。但最好只为正确性而设计。使用智能指针和容器,避免使用普通的
new。
标签: c++ linux memory vector stl