<qandaentry xml:id="faq.memory_leaks">
<question xml:id="q-memory_leaks">
<para>
- <quote>Memory leaks</quote> in containers
+ <quote>Memory leaks</quote> in libstdc++
</para>
</question>
<answer xml:id="a-memory_leaks">
- <note>
- <para>This answer is old and probably no longer be relevant.</para>
- </note>
<para>
- A few people have reported that the standard containers appear
+ Since GCC 5.1.0, libstdc++ automatically allocates a pool
+ of a few dozen kilobytes on startup. This pool is used to ensure it's
+ possible to throw exceptions (such as <classname>bad_alloc</classname>)
+ even when <code>malloc</code> is unable to allocate any more memory.
+ With some versions of <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://valgrind.org/"><command>valgrind</command></link>
+ this pool will be shown as "still reachable" when the process exits, e.g.
+ <code>still reachable: 72,704 bytes in 1 blocks</code>.
+ This memory is not a leak, because it's still in use by libstdc++,
+ and the memory will be returned to the OS when the process exits.
+ Later versions of <command>valgrind</command> know how to free this
+ pool as the process exits, and so won't show any "still reachable" memory.
+ </para>
+ <para>
+ In the past, a few people reported that the standard containers appear
to leak memory when tested with memory checkers such as
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://valgrind.org/"><command>valgrind</command></link>.
Under some (non-default) configurations the library's allocators keep
free memory in a
- pool for later reuse, rather than returning it to the OS. Although
- this memory is always reachable by the library and is never
+ pool for later reuse, rather than deallocating it with <code>delete</code>
+ Although this memory is always reachable by the library and is never
lost, memory debugging tools can report it as a leak. If you
want to test the library for memory leaks please read
<link linkend="debug.memory">Tips for memory leak hunting</link>
<section xml:id="debug.memory"><info><title>Memory Leak Hunting</title></info>
+<para>
+ On many targets GCC supports AddressSanitizer, a fast memory error detector,
+ which is enabled by the <option>-fsanitize=address</option> option.
+</para>
<para>
- There are various third party memory tracing and debug utilities
+ There are also various third party memory tracing and debug utilities
that can be used to provide detailed memory allocation information
about C++ code. An exhaustive list of tools is not going to be
attempted, but includes <code>mtrace</code>, <code>valgrind</code>,
- <code>mudflap</code>, and the non-free commercial product
- <code>purify</code>. In addition, <code>libcwd</code> has a
- replacement for the global new and delete operators that can track
- memory allocation and deallocation and provide useful memory
- statistics.
-</para>
-
-<para>
- Regardless of the memory debugging tool being used, there is one
- thing of great importance to keep in mind when debugging C++ code
- that uses <code>new</code> and <code>delete</code>: there are
- different kinds of allocation schemes that can be used by <code>
- std::allocator</code>. For implementation details, see the <link linkend="manual.ext.allocator.mt">mt allocator</link> documentation and
- look specifically for <code>GLIBCXX_FORCE_NEW</code>.
-</para>
-
-<para>
- In a nutshell, the optional <classname>mt_allocator</classname>
- is a high-performance pool allocator, and can
- give the mistaken impression that in a suspect executable, memory is
- being leaked, when in reality the memory "leak" is a pool being used
- by the library's allocator and is reclaimed after program
- termination.
+ <code>mudflap</code> (no longer supported since GCC 4.9.0), ElectricFence,
+ and the non-free commercial product <code>purify</code>.
+ In addition, <code>libcwd</code>, jemalloc and TCMalloc have replacements
+ for the global <code>new</code> and <code>delete</code> operators
+ that can track memory allocation and deallocation and provide useful
+ memory statistics.
</para>
<para>
For valgrind, there are some specific items to keep in mind. First
of all, use a version of valgrind that will work with current GNU
C++ tools: the first that can do this is valgrind 1.0.4, but later
- versions should work at least as well. Second of all, use a
- completely unoptimized build to avoid confusing valgrind. Third, use
- GLIBCXX_FORCE_NEW to keep extraneous pool allocation noise from
- cluttering debug information.
+ versions should work better. Second, using an unoptimized build
+ might avoid confusing valgrind.
</para>
<para>
- Fourth, it may be necessary to force deallocation in other libraries
- as well, namely the "C" library. On linux, this can be accomplished
+ Third, it may be necessary to force deallocation in other libraries
+ as well, namely the "C" library. On GNU/Linux, this can be accomplished
with the appropriate use of the <code>__cxa_atexit</code> or
<code>atexit</code> functions.
</para>
}
</programlisting>
-
<para>or, using <code>__cxa_atexit</code>:</para>
<programlisting>
valgrind -v --num-callers=20 --leak-check=yes --leak-resolution=high --show-reachable=yes a.out
</programlisting>
+<section xml:id="debug.memory.mtalloc">
+<info><title>Non-memory leaks in Pool and MT allocators</title></info>
+
+<para>
+ There are different kinds of allocation schemes that can be used by
+ <code>std::allocator</code>. Prior to GCC 3.4.0 the default was to use
+ a pooling allocator, <classname>pool_allocator</classname>,
+ which is still available as the optional
+ <classname>__pool_alloc</classname> extension.
+ Another optional extension, <classname>__mt_alloc</classname>,
+ is a high-performance pool allocator.
+</para>
+
+<para>
+ In a suspect executable these pooling allocators can give
+ the mistaken impression that memory is being leaked,
+ when in reality the memory "leak" is a pool being used
+ by the library's allocator and is reclaimed after program
+ termination.
+</para>
+
+<para>
+ If you're using memory debugging tools on a program that uses
+ one of these pooling allocators, you can set the environment variable
+ <literal>GLIBCXX_FORCE_NEW</literal> to keep extraneous pool allocation
+ noise from cluttering debug information.
+ For more details, see the
+ <link linkend="manual.ext.allocator.mt">mt allocator</link>
+ documentation and look specifically for <code>GLIBCXX_FORCE_NEW</code>.
+</para>
+
+</section>
+
</section>
<section xml:id="debug.races"><info><title>Data Race Hunting</title></info>