超出范围</string>后,vector <string>不会清除内存

时间:2013-07-26 02:36:54

标签: c++ linux string memory vector

我遇到了以下问题,我不确定我是错了还是一个非常奇怪的错误。我填充了大量的字符串,并希望它在某一点被清除。这是一个最小的例子

#include <string>
#include <vector>
#include <unistd.h> //sleep
#include <iostream>

int main(){
    {
        std::vector<std::string> strvec;
        for(long i = 0; i < 1000000; ++i){
            std::string out = "This is gonna be a long string just to fill up the memory used by this fucking pthread\n";
            strvec.push_back(out);
        }
        std::cout << "finished loading 1st\n";
        sleep(10); // to monitor any changes    
    }
    std::cout << "out of scope\n";
    sleep(10);
    return 0;
}

我的问题是,如果我使用'top'监视内存使用情况,内存使用量只会减少一小部分(我认为它可能是矢量开销),但最多似乎没有释放。怎么会?我用'long long'测试了相同的场景,但是这里一切都很顺利。

std :: vector引用表明,如果包含的值不是指针,则调用析构函数。虽然字符串似乎不正确......

我很感激每一个答案。

(为方便起见:我正在使用debian linux 64Bit和g ++ 4.7.2)

编辑:感谢目前为止的答案。

到目前为止,我已经使用vagrind massif描述了堆使用情况,并且(是的,实际上正如预期的那样)它可以在应该的位置正确释放。但为什么我实际上看到一个巨大的整数使用的变化,但没有字符串(也在顶部)?

我需要对此有点相当,因为我需要能够在特定时间为多线程服务器应用程序释放内存,这可能会运行数周或更长时间而不会重新启动。我何时才知道C ++内存管理器何时决定将一些内存返回给操作系统?

3 个答案:

答案 0 :(得分:6)

这是使用top命令的具体内容,而不是std::vector的命令。问题是数据结构释放的内存不会释放回操作系统,即top命令监视内存使用情况的级别。操作系统为程序提供的内存保留在程序中,直到C ++的内存管理器决定将某些内存释放回操作系统为止。

这样做的原因是从操作系统分配内存相对昂贵,并且需要在相对较大的块中完成。 C ++运行时库的内存管理器从操作系统“批发”获取内存,然后根据需要将其分发到程序的各个部分。

如果您想验证内存是否确实被回收,请使用监视较低级别内存使用情况的工具,例如valgrind

答案 1 :(得分:4)

即使您正确释放内存,标准库也无需将内存释放回操作系统。

因此,例如,当您第一次分配所有内存时,库会从操作系统中分配一堆虚拟内存地址空间(可能是mmap(2))并将其分配出来。但是当你完成了那个内存时,它会挂起到虚拟地址空间,假设你以后可能需要那个内存,所以它不会调用munmap(2)取消映射虚拟地址空间。

因此,即使已经从程序的角度正确地释放了所有内存,但所有操作系统都看到你分配了一堆虚拟内存但从未释放它。这就是为什么top(1)报告你的内存使用量没有减少的原因,但没有什么值得关注的。当你的程序再次需要内存时,它会从你已经拥有的虚拟地址空间中分配它,所以在所有内存都用尽之前你不会看到你的内存使用量增加。

答案 2 :(得分:0)

如其他答案中所述,内存仍可供您的进程使用,并且在程序退出之前不会释放内存。如果你想要一个能够做到这一点的分配器,你可以使用jemalloc进行检查,它可以将它释放回操作系统,并且在可扩展的多线程应用程序(如facebook)中非常有用,但与任何其他成本一样。