Memory leak

A review of memory leak cases and ways to prevent them.

A memory leak is the reduction in volume of available operating and virtual memory occurring due to errors in the application and resulting in the impossibility to release unnecessary memory, which becomes inaccessible both to other applications and to the damaged application itself.

The end user usually does not know anything about memory leaks. In general this is the very case when the saying “What you do not know will not hurt you” turns out to be true. Nevertheless, it is useful for each user to know what a memory leak is and how it affects both the operation of the application where it takes place and the operation of all the others.

The impossibility to release the memory with one application prevents other applications (alongside with the one having suffered from the leak) from using this memory for work. In fact, it disappears into nowhere, reducing the system resource, which is scarce in itself. A characteristic sign of the presence of memory leaks is the time-consuming performance of the operating system. Due to the continuous shortage of RAM, running applications are in critical lack of resources, and the operating system more and more often has to resort to the possibilities of virtual memory. Virtual memory is much less powerful and performant than operational memory, because it is physically located on a hard disk, and, therefore, the speed of access to it is sensibly lower. Finally it all results in a complete collapse of the system and all the applications running under its control.

Modern programming languages are protected from memory leaks due to their architecture. The fact is that memory leaks are a very common and more than unpleasant accident, and therefore it was one of the main problems that the developers of new programming languages (such as Java, C # and many others) tried to cope with. Nevertheless, there are still a lot of programs written in programming languages without a built-in protection against memory leaks (the same C ++, Delphi). End users have to put up with it as well as to deal with the consequences of errors occurring in these programs. Nevertheless, there exist quite effective tools even for programming languages of this type allowing to detect memory leaks in an already written program. They are usually included into the packages used for application profiling and debugging. These tools are absolutely necessary for programmers who write programs in “unsafe” languages, and especially for testers checking them.

Why Memory Leaks Are Dangerous

Dynamic memory is a limited resource. The dynamic memory of a program is usually managed by the programming language library, which functions over the dynamic memory provided by the operating system.

Memory leaks result in uncontrolled increase of memory consumed by the program. Consequently, architectural restrictions of the execution environment (the operating system, the virtual machine, the PC) sooner or later show themselves, and it becomes thus impossible to allocate a new volume of memory to the program. In this case, the program in request of memory usually makes an emergency stop. This can also occur when the program having suffered from leaks exhausts all the memory of the PC reducing the performance of another program requesting the memory.

Ways of Prevention of Memory Leaks

There are various ways of prevention of memory leaks:

  1. Rejection of dynamic memory

For example, FORTRAN-77 has definitely refused to use mechanisms for dynamic allocation of memory, what excludes this kind of errors, but restricts the functionality of programs in an important way.

  1. Smart pointers

Smart pointers allow to coordinate to a certain extent the lifetime of the pointer and the one of the object it refers to. However, the use of smart pointers does not help if there are circular references between objects.

  1. Garbage collection

Some programming languages (for example, Java, .NET platform languages) provide tools allowing to release the unused memory automatically. Garbage collectors also solve the problem of circular  references, but garbage collection is a resource-consuming operation. These tools are used on the account of the system performance, and, what is the most important, garbage collection provokes unexpected breaks in the work of the program, what is unacceptable in real-time systems.

  1. Program restart

When memory leaks cannot be eliminated, for example, when using a code provided as a program module and written by third-party developers, there is a unique method to apply in order to ignore leaksThe code, which is subject to leakage, is placed in a separate program, and this program is restarted within the specified periodicity. The program is started and restarted by an external program, which provides the source data and collects the results. Since upon completion of the program all the memory it requested from the operating system comes back, but again, to the operating system, it does not allow leaks to cause irreversible harm.

Memory Leaks Detection

There are special profiling programs for professional programming languages that allow you to detect, among other things, memory leaks.

Multi-platform universal solutions:

  • gprof[en] (Linux/Unix/*BSD) — several implementations of the traditional profiler, requiring a compiler to instrument the program
  • VTune (Windows/Linux) — a commercial product of Intel
  • Intel® Single Event API (Windows/Linux/Android/MAC OS/…) – a non-commercial open source product of Intel
  • CodeAnalyst (Windows/Linux) — free program from AMD company

Solutions for separate operating systems

  • AQtime (Windows)
  • Instruments[en] (earlier Shark; Mac OS X)
  • Perf (Linux)[en] — a system for profiling processes and the kernel implemented in the Linux kernel
  • oprofile (Linux) — an earlier version of Linux system profiler
  • Valgrind (Linux) — a dynamic binary program analysis tool, containing 2 plugins for performance profiling – Cachegrind and Callgrind

For some of programming languages (similar tools can be built into the development environment):

  • Xdebug — PHP script profiling tool
  • XHProf — PHP language profiler

An example of programs profiling the allocation of memory consumption:

  • dotTrace (.NET)
  • Valgrind (Linux) — several plugins for memory profiling.

For some programming languages, there exist static code analyzers that detect program elements potentially capable of causing logical errors, including memory leaks. A primitive version of this type of analyzer is implemented by almost any high-level language compiler, generating warning messages to inform that the program contains certain constructions that do not formally violate the syntax of the language, but potentially erroneous.

Static analysis tools:

C/C++:

  • BLAST
  • Clang Static Analyzer (built in Clang)[10]
  • Coverity
  • PC-Lint
  • lint and lock_lint, included in Sun Studio
  • Cppcheck (Cppcheck on sf)
  • Parasoft C/C++Test (en.)rus.
  • SourceAnalyzer (also Fortran and x86 asm)
  • PVS-Studio
  • LDRA Testbed (en.)rus.
  • Polyspace (en.)rus.
  • QA-C (en.)rus.
  • Cantata++ (en.)rus.

Java:

  • FindBugs (FindBugs on sf)
  • Parasoft JTest (en.)rus.
  • fbinfer

.NET:

  • .NET Compiler Platform (Roslyn) — a compiler framework for C # and VB.NET that provides an interface for the analyzer
  • FxCop
  • NDepend
  • PVS-Studio
  • ReSharper
  • StyleCop

Python:

  • Pychecker (en.)rus.
  • Pylint (en.)rus.
  • Pyflakes

Others:

  • T-SQL Analyzer — a tool that can view program modules in databases managed by Microsoft SQL Server 2005 or 2008 and detect potential problems arising because of the poor quality of the code
  • АК-ВС 2 (A search tool for undeclared features, used to detect dangerous templates by CWE (en.)rus.)
  • SonarQube — a platform for analyzing and managing the quality of the code with the support of various programming languages via a plug-in system
  • AppChecker — a commercial static code analyzer for automatic detection of defects in the source code of applications developed in C #, C / C ++, Java, PHP
  • Svace — a static analysis tool, meeting all the requirements for the analyzer of industrial quality. It supports the following programming languages: C / C ++, Java, C #

There are also libraries for memory use debugging, helping to monitor memory allocation and release while the program is running.

  • AQtime
  • dmalloc
  • Electric Fence
  • Intel Parallel Inspector
  • MemCheck
  • Sun Studio Runtime Checking (RTC)
  • TotalView
  • Valgrind
  • Spider

Leave a Reply

Your email address will not be published. Required fields are marked *