0

My code is something like this. The vector in question is a vector of dynamic bitset from the boost library:

while(someCondition){
      vector<dynamic_bitset<> > myvector;  
      //some code here
      myvector.push_back(dynamic_bitset<> x) ;
      //some more code

      //myvector use is over now, release it.
      myvector.clear();
      myvector.shrink_to_fit();
      //or swap myvector with empty vector
}  

As above, myvector is created and cleared every iteration of the while loop. I'm analyzing the memory usage of this code by running it in GDB, and in parallel, looking at the memory consumption displayed by the top command. (There are reasons I can't use valgrind).

I can see that when I push_back new elements into myvector the memory usage percentage for this program goes up in the top command output. However, when I clear the vector and shrink it (or even if I swap it with empty vector), the usage percentage under top doesn't lower. So, in every iteration of the loop the memory usage keeps increasing and eventually uses up most of the RAM.

How do I prevent this from happening? I'd like the memory of the vector to be released back to the OS every iteration of the while loop. Perhaps, top is not the right way to analyze memory but I've no other option. Any ideas?

sanjeev mk
  • 4,276
  • 6
  • 44
  • 69
  • Most standard libraries allocate big blocks of memory from the OS, then break them into little pieces to satisfy allocation requests from the program. Most only release those big blocks back to the OS when the program exits, or (possibly) when you call some special, internal function to tell them to release memory if they can (e.g., `_heapmin()` with Microsoft compilers). – Jerry Coffin May 13 '15 at 23:22
  • @SleuthEye the custom data type is the dynamic bitset from Boost. – sanjeev mk May 13 '15 at 23:28
  • note that according to [cppreference](http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit): `shrink_to_fit` "... is a non-binding request to reduce capacity() to size(). It depends on the implementation if the request is fulfilled". See also [this related question](http://stackoverflow.com/q/23502291/2994596) – SleuthEye May 13 '15 at 23:34
  • see http://stackoverflow.com/questions/1119134/how-do-malloc-and-free-work `new` and `delete` (which are what `std::vector` most likely uses internally) are usually implemented by calling `malloc` and `free` – programmerjake May 13 '15 at 23:52
  • Doing a bit of looking, it appears gcc does release free memory back to the OS if there's enough of it. It looks like [`mallopt(M_TRIM_THRESHOLD, ...`](http://man7.org/linux/man-pages/man3/mallopt.3.html) should let you adjust that threshold low enough to get it to at least try to release extra memory back to the OS when desired (but be aware that messing with this is probably a poor idea for most code/circumstances). – Jerry Coffin May 14 '15 at 00:13
  • You could adapt the allocator [in this answer](http://stackoverflow.com/a/11703840/315052) and change the arena's allocate and deallocate functions to directly call `mmap()` and `munmap()`. – jxh May 14 '15 at 00:24

0 Answers0