如果我只给它指向我的对象的指针,std :: vector占用了什么内存? [英] What memory is occupied by std::vector if I only give it a pointer to my object?

查看:117
本文介绍了如果我只给它指向我的对象的指针,std :: vector占用了什么内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有些事情我不明白,我非常感谢一些澄清。我知道有很多关于std ::容器和内存没有释放,但我还是不明白一个特定的事实。



下面是一个最小的程序,代表一个问题,我在我的生产系统。在评论中,在Ubuntu上等待std :: cin时,有从/ proc / PROC_NUM / status读取的内存消耗。问题也在评论中。

  #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 {
array [i] = random();
}
}

〜MyObject()
{
delete [] array;
}

public:
float * array;
};


int main(int argc,char * argv [])
{
char a;
const int count = 100;

std :: cout<<输入后开始<< std :: endl;
std :: cin>>一个;
// VmSize:12704 kB
{
std :: vector< MyObject *> vec;
for(int i = 0; i {
vec.push_back(new MyObject);
}

std :: cout<<输入后释放<< std :: endl;
std :: cin>>一个;
// VmSize:13100 kB,好吧,MyObjects填充400kB(我想要的)

for(int i = 0; i {
delete vec [i];
vec [i] = NULL;
}

std :: cout<<输入后,向量范围外运行<< std :: endl;
std :: cin>>一个;
// VmSize:13096 kB,为什么400k不能释放呢?
}

std :: cout<<输入后关闭<< std :: endl;
std :: cin>>一个;
// VmSize:12704 kB,为什么现在大约400k释放?这里释放的唯一的东西是指针的向量。

return 0;
}

如果我使用MyObjects数组,内存会在删除后立即释放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 {
array [i] = random();
}
}

〜MyObject()
{
delete [] array;
}

public:
float * array;
};


int main(int argc,char * argv [])
{
char a;
const int count = 100;

std :: cout<<输入后开始<< std :: endl;
std :: cin>>一个;
// VmSize:12700 kB
{
MyObject * vec(new MyObject [count]);

std :: cout<<输入后释放<< std :: endl;
std :: cin>>一个;
// VmSize:13096 kB,alright,about 400k again
delete [] vec;

std :: cout<<输入后的向量范围外<< std :: endl;
std :: cin>>一个;
// VmSize:12700 kB,400k再次释放,完美。
}

std :: cout<<输入后关闭<< std :: endl;
std :: cin>>一个;
// VmSize:12700 kB,没有改变,如预期
return 0;
}

我读的答案告诉我不能相信操作系统的内存目前我在Linux上使用/ prop / PROC_NO / status的输出)。我可以用什么来监视内存消耗?我试过在Mac的XCode仪器和那里,我甚至没有那个问题相同。在第一种情况下,意味着内存消耗等于第二种情况。



在Ubuntu上,我尝试了不同版本的gcc和clang, p>

在我的生产系统中,有一个std :: map而不是std :: vector,但问题是一样的。

/ p>

VMSize反映操作系统实际必须使用哪些内存来满足程序的内存要求。例如,如果你使用 malloc new [] 或anonymous



此外,大多数运行时库都分配了大容量的内存空间, hunks和对象分配然后是来自这些大块的分片;在释放对象之后,只有该块中的空间被标记为空闲,并且可以被再循环用于下一次分配。释放这么大的内存块的典型提示是,如果从它分配的所有对象都被释放,并且没有其他对象驻留在其中。所以你的std :: vector和你手动分配的对象很可能从同一个hunk分配,而std :: vector实例阻止它返回到系统。 但这只是推测!细节取决于使用的C ++运行时库。


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.

解决方案

The VMSize has little to do with the entering and leaving of scopes in a scope language (are ware that there are programming environments that don't have scope?).

The VMSize reflects which memory the operating system actually has to use to satisfy a program's memory requirement. For example if you allocate a large block of memory using malloc, new[] or anonymous mmap the address space is merely reserved, but not occupied, thereby not showing up in the VMSize.

Furthermore most runtime libraries allocate memory in large hunks and object allocations are then slices from these large hunks; after freeing an object only the space in the hunk is marked as free and may get recycled for the next allocation. A typical cue to free such a large hunk of memory is, if all objects allocated from it are freed and no further object resides in it. So your std::vector and the objects you manually allocated are likely allocated from the same hunk and the std::vector instance sitting around prevents it from being returned to the system. But this is all just conjecture! The details depend on the C++ runtime library used.

这篇关于如果我只给它指向我的对象的指针,std :: vector占用了什么内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆