When using a very large vector of vectors we've found that part of the memory is not released.
#include <iostream> #include <vector> #include <unistd.h> void foo() { std::vector<std::vector<unsigned int> > voxelToPixel; unsigned int numElem = 1<<27; voxelToPixel.resize( numElem ); for (unsigned int idx=0; idx < numElem; idx++) voxelToPixel.at(idx).push_back(idx); } int main() { foo(); std::cout << "End" << std::endl; sleep(30); return 0; }
That leaves around 4GB of memory hanging until the process ends.
If we change the for
line to
for (unsigned int idx=0; idx < numElem; idx++) voxelToPixel.at(0).push_back(idx);
the memory is released.
Using gcc-4.8
on a linux machine. We've used htop
to track the memory usage on a computer with 100 GB of RAM. You will need around 8 GB of RAM to run the code. Can you reproduce the problem? Any ideas on why that is happening?
EDIT: We've seen that that does not happen in a Mac (with either gcc
or clang
). Also, in linux, the memory is freed if we call foo
two times (but happens again the third time).
No, memory are not freed. In C++11, you can use the shrink_to_fit method for force the vector to free memory. Show activity on this post.
As mentioned above, std::vector is a templated class that represents dynamic arrays. std::vector typically allocates memory on the heap (unless you override this behavior with your own allocator). The std::vector class abstracts memory management, as it grows and shrinks automatically if elements are added or removed.
So there is no surprise regarding std::vector. It uses 4 bytes to store each 4 byte elements.
Vectors are assigned memory in blocks of contiguous locations. When the memory allocated for the vector falls short of storing new elements, a new memory block is allocated to vector and all elements are copied from the old location to the new location. This reallocation of elements helps vectors to grow when required.
Small allocations (up to 128kb by default, I think) are managed by an in-process heap, and are not returned to the OS when they're deallocated; they're returned to the heap for reuse within the process. Larger allocations come directly from the OS (by calling mmap
), and are returned to the OS when deallocated.
In your first example, each vector only needs to allocate enough space for a single int
. You have a hundred million small allocations, none of which will be returned to the OS.
In the second example, as the vector grows, it will make many allocations of various sizes. Some are smaller than the mmap
threshold, these will remain in the process memory; but, since you only do this to one vector, that won't be a huge amount. If you were to use resize
or reserve
to allocate all the memory for each vector before populating it, then you should find that all the memory is returned to the OS.
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