Linux Allocator Does Not Release Small Chunks of Memory

限于喜欢 提交于 2019-11-26 20:38:11

This behaviour is intentional, there is a tunable threshold that glibc uses to decide whether to actually return memory to the system or whether to cache it for later reuse. In your first program you make lots of small allocations with each push_back and those small allocations are not a contiguous block and are presumably below the threshold, so don't get returned to the OS.

Calling malloc_trim(0) after clearing the list should cause glibc to immediately return the top-most region of free memory to the system (requiring a sbrk system call next time memory is needed.)

If you really need to override the default behaviour (which I wouldn't recommend unless profiling reveals it actually helps) then you should probably use strace and/or experiment with mallinfo to see what's actually happening in your program, and maybe using mallopt to adjust the threshold for returning memory to the system.

It keeps the smaller chunks available in case you request them again. It is a simple caching optimization, and not behaviour to be concerned about.

Typically, the memory allocated by new will only be returned to the system when the process terminates. In the second case, I suspect that libc is using a special allocator for very large continuous blocks, which does return it, but I'd be very surprised if any of your new char[1024] were returned, and on many Unices, even the large block won't be returned.

(Editing down my answer, since there really isn't any issue here.)

As has been noted, there isn't really an issue here. Johnathon Wakely hits the nail on the head.

When the memory utilization is not what I expect it to be on Linux, I usually start my analysis using the mtrace tool, and analyzing the /proc/self/maps file.

mtrace is used by bracketing your code around two calls, one to starts the trace, and one that ends it.

  mtrace();
  {
      // do stuff
  }
  muntrace();

The mtrace calls are only active if the MALLOC_TRACE environment variable is set. It specifies the name of the file for the mtrace logging output. This logging output can then be analyzed for memory leaks. A command line program called mtrace can be used to analyze the output.

$ MALLOC_TRACE=mtrace.log ./a.out
$ mtrace ./a.out mtrace.log

The /proc/self/maps file provides a list of memory mapped regions in use by the current program, including anonymous regions. It can help identify regions which are particularly large, and then additional sleuthing is needed to determine what that region is associated with. Below is a simple program to dump the /proc/self/maps file to another file.

void dump_maps (const char *outfilename) {
  std::ifstream inmaps("/proc/self/maps");
  std::ofstream outf(outfilename, std::ios::out|std::ios::trunc);
  outf << inmaps.rdbuf();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!