-2

I have a very large vector as follows.

vector<vector<int>> a(100000, vector<int>(100000);
// do some work using a here
......

After the work is done, I use

vector<vector<int>>().swap(a);

in order to free the memory used by "a" immediately. I add

sleep(100)

after the swap and use "top" command to see whether memory usage is reduced immediately. But I observe that nothing has changed. What happens here?

  • 8
    What specifically are the symptopms of it not working? What are you measuring to see whether it worked? – Useless Jan 14 '20 at 09:51
  • 3
    How are you measuring memory? There is no guarantee C/C++ will return the virtual memory to the OS, or how long until the OS otherwise considers that memory inactive. – Fire Lancer Jan 14 '20 at 09:52
  • When you say "memory", are you talking about address space (virtual memory) or physical memory (RAM)? – David Schwartz Jan 14 '20 at 09:53
  • 3
    The memory is freed. Do not expect to see that immediately in the Task Manager if this is how you claim that it isn't. – Michael Chourdakis Jan 14 '20 at 10:04
  • @Useless I used the "top" command and observed that the memory was not released. Is "top" not appropriate here? – yicepeh969 Jan 14 '20 at 10:10
  • @MichaelChourdakis Yes. Is the information shown in Task Manager not correct? – yicepeh969 Jan 14 '20 at 10:11
  • The information shown in Task Manager and in top is correct, but almost irrelevant, because you don't understand how process memory allocation behaves. Shrinking your vector returns memory to the process free store, but probably keeps it for later reuse instead of returning it directly to the OS. – Useless Jan 14 '20 at 10:18
  • It is correct from the point of view of Windows. Your program still has that memory. The allocator will reuse it when asked to allocate something else. It is also correct from the C++ object model, 100000 calls to `~std::vector()` occured, and 10000000000 `int`s ceased to be. – Caleth Jan 14 '20 at 10:18
  • 2
    @yicepeh969 As has already been pointed out, the information shown in Task Manager reflects information the OS has about your running process. The sort of memory allocation that `std::vector` uses by default (`new` and `delete`) is typically handled by a runtime layer inside your process, not by the OS directly. Just because you returned a bunch of memory to the memory allocator that `new` and `delete` use underneath doesn't mean that memory allocator also returned it to the OS. It just means the memory allocator may start handing out bits of this memory again next time you allocate something… – Michael Kenzel Jan 14 '20 at 10:18
  • 1
    There's a similar question answered [here](https://stackoverflow.com/a/29529288/212858) - I can't find a better duplicate immediately, but it has more detail than fits in a comment. – Useless Jan 14 '20 at 10:24

2 Answers2

3

To immediately clear vector out from the memory you should do :

v.clear();
v.shrink_to_fit();
Ladence
  • 244
  • 2
  • 9
  • 7
    [cppreference](https://en.cppreference.com/w/cpp/container/vector/shrink_to_fit): "It is a non-binding request to reduce `capacity()` to `size()`. **It depends on the implementation whether the request is fulfilled.**" – Evg Jan 14 '20 at 09:53
  • That doesn't change anything at all (swapping with temporary empty vector was the way to do it before shrink_to_fit() was introduced), but memory still doesn't have to be returned to OS immediately. – Aconcagua Jan 14 '20 at 10:29
  • @Aconcagua sure, but i didn't know that author meaned OS memory by "memory". – Ladence Jan 14 '20 at 10:31
  • @Aconcagua the question had been edited after my answer – Ladence Jan 14 '20 at 10:32
  • Ah, missed that, sorry. That's the problem with those essential edits, invalidating previously totally fine answers... – Aconcagua Jan 14 '20 at 10:34
2

It should work you might have error elsewhere in the code or you don't judge correctly whether the memory is freed.

You could make the deallocation more general - so it'll work on anything without performing any unnecessary operations in the swap. Swap consists of three moves. You can achieve the same result with a move and default reinitialization.

   {auto x=std::move(a);a={};}

x steals a's memory and gets destroyed after leaving the scope. The a={}; isn't be necessary in most cases but according to standart after moving from object is allowed to be in a rather weird state.

ALX23z
  • 4,456
  • 1
  • 11
  • 18