malloc_count
This Component is a modified version of the original code, intended to provide basic heap monitoring for the Sming Host Emulator.
The following is the original README.
Introduction
malloc_count
provides a set of source code tools to measure the amount of
allocated memory of a program at run-time. The code library provides
facilities to
measure the current and peak heap memory allocation, and
write a memory profile for plotting, see the figure on the right.
Furthermore, separate
stack_count
function can measure stack usage.
The code tool works by intercepting the standard malloc()
, free()
, etc
functions. Thus no changes are necessary to the inspected source code.
See http://panthema.net/2013/malloc_count for the current version.
Intercepting Heap Allocation Functions
The source code of malloc_count.[ch]
intercepts the standard heap allocation
functions malloc()
, free()
, realloc()
and calloc()
and adds simple
counting statistics to each call. Thus the program must be relinked for
malloc_count
to work. Each call to malloc()
and others is passed on to
lower levels, and the regular malloc()
is used for heap allocation.
Of course, malloc_count
can also be used with C++ programs and maybe even
script languages like Python and Perl, because the new
operator and most
script interpreters allocations all are based on malloc
.
The tools are usable under Linux and probably also with Cygwin and MinGW, as they too support the standard Linux dynamic link loading mechanisms.
Memory Profile and stack_count
The malloc_count
source is accompanied by two further memory analysis tools:
stack_count
and a C++ header called memprofile.h
.
In stack_count.[ch]
two simple functions are provided that can measure the
maximum stack usage between two points in a program.
Maybe the most useful application of malloc_count
is to create a
memory/heap profile of a program (while it is running). This profile can
also be created using the well-known
valgrind tool “massif”,
however, massif is really slow. The overhead of malloc_count
is much smaller,
and using memprofile.h
a statistic file can be produced, which is directly
usable with Gnuplot.
The source code archive contains two example applications: one which queries
malloc_count
for current heap usage, and a second which creates the memory
profile in the figure on the right. See the STX B+ Tree library for another,
more complex example of a memory profile.
Downloads
See http://panthema.net/2013/malloc_count for the current version.
The source code is published under the MIT License (MIT), which is also found in the header of all source files.
Short Usage Guide
Compile malloc_count.c
and link it with your program. The source file
malloc_count.o
should be located towards the end of the .o
file
sequence. You must also add “-ldl
“ to the list of libraries.
Run your program and observe that when terminating, it outputs a line like
malloc_count ### exiting, total: 12,582,912, peak: 4,194,304, current: 0
If desired, increase verbosity
by setting
log_operations = 1
at the top ofmalloc_count.c
and adaptinglog_operations_threshold
to output only large allocations, orby including
malloc_count.h
in your program and using the user-functions define therein to output memory usage at specific checkpoints. See the directorytest-malloc_count/
in the source code for an example.
Tip: Set the locale environment variable LC_NUMERIC=en_GB
or similar to get
comma-separation of thousands in the printed numbers.
The directory test-memprofile/
contains a simple program, which fills a
std::vector
and std::set
with integers. The memory usage of these
containers is profiled using the facilities of memprofile.h
, which are
described verbosely in the source.
Thread Safety
The current statistic methods in malloc_count.c
are not thread-safe.
However, the general mechanism (as described below) is per-se thread-safe. The
only non-safe parts are adding and subtracting from the counters in
inc_count()
and dec_count()
.
The malloc_count.c
code contains a #define THREAD_SAFE_GCC_INTRINSICS
,
which enables use of gcc’s intrinsics for atomic counting operations. If you
use gcc, enable this option to make the malloc_count
tool thread-safe.
The functions in memprofile.h
are not thread-safe. stack_count
can also be
used on local thread stacks.
Technicalities of Intercepting libc
Function Calls
The method used in malloc_count
to hook the standard heap allocation calls is
to provide a source file exporting the symbols “malloc
“, “free
“, etc. These
override the libc symbols and thus the functions in malloc_count
are used
instead.
However, malloc_count
does not implement a heap allocator. It loads the symbols
“malloc
“, “free
“, etc. directly using the dynamic link loader “dl
“ from the
chain of shared libraries. Calls to the overriding “malloc
“ functions are
forwarded to the usual libc allocator.
To keep track of the size of each allocated memory area, malloc_count
uses a
trick: it prepends each allocation pointer with two additional bookkeeping
variables: the allocation size and a sentinel value. Thus when allocating n
bytes, in truth n + c bytes are requested from the libc malloc()
to save the
size (c is by default 16, but can be adapted to fix alignment problems). The
sentinel only serves as a check that your program has not overwritten the size
information.
Closing Credits
The idea for this augmenting interception method is not my own, it was borrowed from Jeremy Kerr http://ozlabs.org/~jk/code/.
Written 2013-01-21, 2013-03-16, and 2014-09-10 by Timo Bingmann tb@panthema.net
API Documentation
-
namespace MallocCount
Typedefs
-
using Callback = std::function<void(size_t current)>
Callback function type.
- Param current:
Current allocated bytes
Functions
-
size_t getCurrent(void)
Get the currently allocated amount of memory.
-
size_t getPeak(void)
Get the peak memory allocation.
-
void resetPeak(void)
Reset the peak memory allocation to current.
-
size_t getTotal(void)
Get the total cumulative memory allocation.
-
void resetTotal(void)
Reset the total cumulative memory allocation to zero.
-
size_t getAllocCount(void)
Get the total number of allocations.
-
void setAllocLimit(size_t maxBytes)
Set an allocation limit.
- Parameters:
maxBytes – Specify 0 for no limit
-
void setCallback(Callback callback)
Set a callback function that is invoked on each change of the current allocation.
Note
The callback function must not use malloc()/realloc()/free() or it will go into an endless recursive loop!
-
void enableLogging(bool enable)
Enable/disable logging.
-
void setLogThreshold(size_t threshold)
Set minimum allocation size for log output (when enabled)
-
using Callback = std::function<void(size_t current)>
References
Used by
Host Heap support Component
Basic Graphics Sample
Basic Alexa Sample
RingTone Player Sample
SmingTest Library
Basic SSL Sample
Environment Variables
SoC support
esp32
esp32c2
esp32c3
esp32s2
esp32s3
esp8266
host
rp2040
rp2350