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?
This is a specific of using the top
command, not of the std::vector
. The issue is that the memory freed by data structures is not released back to the operating system, the level at which the top
command monitors memory usage. The memory the OS has given your program remains with your program until the memory manager of C++ decides that it's time to free some memory back to the operating system.
The reason for this is that allocating memory from the operating system is relatively expensive, and it needs to be done in relatively large chunks. The memory manager of the C++ runtime library obtains memory from the OS "wholesale", and then parcels it out to the parts of your program as needed.
If you would like to verify that the memory does indeed get reclaimed, use a tool that monitors memory usage at a lower level, such as valgrind
.
Even if you free the memory properly, the standard library doesn't necessary free the memory back to the OS.
So for example, when you first allocate all of the memory, the library allocates a bunch of virtual memory address space from the OS (likely with mmap(2)
) and doles it out. But when you're done with that memory, it hangs onto the virtual address space under the assumption that you might want that memory back later, so it doesn't call munmap(2)
to unmap the virtual address space.
Hence, even though all of the memory has been properly freed from your program's perspective, all the OS sees is that you allocated a bunch of virtual memory but then never freed it. That's why top(1)
reports your memory usage as not decreasing, but it's nothing to be concerned about. When your program needs memory again, it'll allocate it from the virtual address space which you already have, so you won't see your apparent memory usage increase until all of that memory has been used up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With