Linux and Memory Leaks

How OS handles memory leaks

Recommended reading : Operating Systems: Three Easy Pieces

On common OSes (e.g. Linux, Windows, MacOSX, Android) each process has its own virtual address space (and the heap memory, e.g. used for malloc or mmap, is inside that virtual address space), and when the process terminates, its entire virtual address space is destroyed.

So memory leaks don't survive the process itself.

There could be subtle corner cases (e.g. leaks on using shm_overview(7) or shmget(2)).

Read (for Linux) proc(5), try cat /proc/self/maps, and see also this. Learn to use valgrind and the Address Sanitizer.

Read also about Garbage Collection. It is quite relevant.

Linux and memory leaks

Does Linux automatically re-claim all memory used by an applications immediately?

No, but yes in the sense that you're implying. All virtual memory belonging to the process are released. Frames that aren't shared are made available to other processes.

If so then should the application really bother about freeing all memory before exit?

Yes, for several reasons:

  • You may decide to extend the code toward other purposes in the future, adding clean-up later on may be difficult.
  • You have excessive memory usage, and actually need the virtual memory space being "wasted".
  • You need to track down some bugs: Not carefully releasing resources acquired will make debugging very difficult.

There are situations that could arise when not freeing memory is what you want, generally these will be performance related, and only specific to those situations.

Is it really worth to call the destructor of every class in a multi-threading application before making a call to exit(0)?

This is pretty much the same as the last question. Also note that not releasing resources from third party, and OS libraries is effectively the same as not freeing memory.

If Linux always re-claims all memory used by an application immediately, then memory leaks are only the dangling pointers which the application has created and that too only it its lifetime.

Yup. The only time this theory breaks down is when resources held are global, and don't go away at process termination. Shared memory, poorly designed third party libraries, temporary files etc. are examples of these.

Lightweight memory leak debugging on linux

Surprisingly, I was unable to find anything like Microsoft's UMDH in open-source domain or available for immediate download. (I also looked at Google Heap Leak Checker but it is more like Valgrind rather than to UMDH). So I ended up writing the tool myself using malloc instrumentation project as a reference point:

https://github.com/glagolig/heapwatch

The tool has number of limitations, but it worked just fine for my purposes.

How to check for memory leaks in a large scale c++ Linux application?

First of all...

and we reached the point when it is mandatory to make a roundup of checks for memory leaks.

This, actually, is a problem of methodology. Correctness should be the primary goal of any software piece and not an afterthought.

I will suppose though that you now realize this and how much easier it would have been to identify the problems had you been running an instrumented unit test at each commit.


So, what to do now ?

  • Runtime detection:

    • Try to make Valgrind work, you probably have some environmental issues
    • Try ASan, ThreadSan and MemSan; they are not trivial to setup under Linux but oh so impressive!
    • Try instrumented builds: tcmalloc includes a heap-checker for example
    • ...
  • Compile time detection:

    • Turn on the warnings (preferably with -Werror) (not specific to your issue)
    • Use static analysis, such as Clang's, it may spot unpaired allocation routines
    • ...
  • Human detection:

    • Code reviews: make sure all resources are allocated within RAII classes
    • ...

Note: using only RAII classes helps removing memory leaks, but does not help with dangling references. Thankfully, detecting dangling references is what ASan does.


And once you have patched all the issues, make sure that this becomes part of the process. Changes should be reviewed and tested, always, so that rotten eggs are culled immediately rather than left to stink up the code base.

Under what condition does Linux Kernel kills a process leaking memory?

Memory leaks can cause your system memory to get low. If the memory gets very low, the OOM(Out Of Memory) killer will be invoked to try to recover from low memory state. The OOM Killer will terminate one or more processes that consume more memory and are of least importance(low priority). Normally, the OOM killer will be invoked incase there is no user address space available or if there is no page available.

OOM killer uses select_bad_process(),badness() to determine and kill the process. These functions determine the process by assigning points/score for all the processes based on various factors such as VM size of process, VM size of its children, uptime, priority, whether it does any hardware access, whether it is swapper or init or kernel thread. The process with highest points/ score(badness) gets terminated/killed.

Also, checkout whether the overcommit behaviour of kernel (/proc/sys/vm/overcommit_memory, /proc/sys/vm/overcommit_ratio) and the limit on the address space for the processes are appropriate.

Valgrind is a very handy tool in such scenarios in identifying memory leaks.



Related Topics



Leave a reply



Submit