矢量<string>在超出范围后不清除内存

vector<string> does not clear memory after out of scope

本文关键字:范围 清除 内存 lt string gt 矢量      更新时间:2023-10-16

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

#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 pthreadn";
            strvec.push_back(out);
        }
        std::cout << "finished loading 1stn";
        sleep(10); // to monitor any changes    
    }
    std::cout << "out of scopen";
    sleep(10);
    return 0;
}

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

std::vector引用声明,如果包含的值没有指针,则会调用析构函数。字符串似乎不正确。。。

我感谢每一个答案。

(为了方便:我使用的是带有g++4.7.2的debian-linux-64Bit)

编辑:谢谢你到目前为止的回答。

到目前为止,我已经用vagrind massif描述了堆的使用情况,并且(是的,实际上正如预期的那样)它在应该的时候得到了适当的释放。但是,为什么我实际上看到一个大整数的用法发生了变化,而字符串(也是顶部的whithin)却没有?

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

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

原因是从操作系统中分配内存相对昂贵,并且需要以相对较大的块来完成。C++运行库的内存管理器从操作系统"批发"获得内存,然后根据需要将其打包到程序的各个部分。

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

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

因此,例如,当您第一次分配所有内存时,库会从操作系统中分配一堆虚拟内存地址空间(可能是mmap(2))并将其分配出去。但是,当您处理完该内存时,它会挂在虚拟地址空间上,假设您稍后可能希望该内存返回,因此它不会调用munmap(2)来取消映射虚拟地址空间。

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

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