7

i've encountered the following problem, and i'm not really sure whether i am wrong or its a really weird bug. I fill a huge array of strings and want it to be cleared at a certain point. Here's a minimal example

#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;
}

My Problem is, if i monitor memory usage with 'top', the memory usage decreases just by a very small amount (i think its probably the vector overhead), but the most seems not freed. How comes? I tested the same scenario with 'long long', but here everything went right.

The std::vector reference states, that, if the contained values are no pointers, the destructors are invoked. Seems not true for string though...

I appreciate every answer.

(for convenience: i'm using debian linux 64Bit with g++ 4.7.2)

EDIT: thanks for the answers so far.

by now i have profiled heap usage with vagrind massif, and (yeah, actually as expected) it gets properly freed at the point it should. But why do i in fact see a change in usage with a huge integer, but not with the strings (also whithin top)?

I need to be a little considerable about that, because i need to be able to free my memory at certain times for a multithreaded server application, which will probably run several weeks or more without being restarted. When do i actually know when the C++ memory manager decides to give some mem back to the OS?

4

3 回答 3

6

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

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

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

于 2013-07-26T02:43:19.483 回答
5

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

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

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

于 2013-07-26T02:41:51.873 回答
0

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

于 2013-07-26T03:05:30.330 回答