There is something I don't understand and I would highly appreciate some clarification. I know there is a lot around about std::containers and memory not freed, but I still don't understand one particular fact.
Below is a minimal program that represents a problem I have in my productive system. In comments there is the memory consumption read from /proc/PROC_NUM/status while waiting for std::cin on Ubuntu. Questions are also in the comments.
#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;
}
If I use an array of MyObjects instead, memory is freed immediately after I delete it:
#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;
}
I read answers telling that I can't trust the OS' memory numbers (currently I used the output of /prop/PROC_NO/status on Linux). What instead could I use to monitor the memory consumption? I tried the same on Mac in XCode Instruments and there, I don't even have that problem. Meaning memory consumption in the first case is equal to the second case.
On Ubuntu, I tried different versions of gcc and clang and they all showed the same behavior.
In my productive system, there is a std::map instead of a std::vector, but the problem is the same.