Memory profiler for C
You may want to take a look at MemProf.
How to profile memory usage?
Use massif, which is part of the Valgrind tools. massif-visualizer can help you graph the data or you can just use the ms_print
command.
memory profiling for C program
Find the memory size of the object
If you want to know the size of your program on disk plus the size of text and data in RAM, on Linux/Unix you can use the size command:
$> size /bin/cat
text data bss dec hex filename
43422 1720 2472 47614 b9fe /bin/cat
The outputs of size are the memory sizes of different parts of the object file:
- text: (code segment) executable instructions
- data: (data segment) initialised global variables
- bss: (block started by symbols) statically-allocated variables
The last two columns, dec and hex, are respectively the sum of the other three (the overall size) in decimal and hexadecimal.
The size you are asking for is: the output of ls (that gives you the size on disk) plus the dec part of the output of the size command that gives you the size on RAM.
See also these posts: http://www.cyberciti.biz/faq/linux-find-size-of-text-data-segment-bss-uninitialized-data/, how to know the memory footprint of my binary executable
Find the memory footprint
When referring to a software application the footprint indicates the size of the memory consumed by the running process (runtime memory requirements).
Said that, it is clear that you should check the memory footprint when the process is running. I think (and other posts confirm it) that the only real option is to use a tool like valgrind.
Profile your application with valgrind
You can profile the memory using the Massif tool. Massif is an heap profiler but can also measure the size of the stack.
valgrind --tool=massif --stacks=yes
This will give you both the heap and stack memory usage.
Then the information are stored in the file massif.out.????
that you can read with
ms_print massif.out.?????
The first output in the file is a nice chart of the memory usage during the running time.
--------------------------------------------------------------------------------
Command: ./myprog -f d5.ini
Massif arguments: --stacks=yes
ms_print arguments: massif.out.24377
--------------------------------------------------------------------------------
MB
5.292^ ##
| @ : : @@ : : # :::: : :
| @:::: :: : :@:@@::::::::::::@ :::::::::::::# ::::@::::@::::::::
| @:: ::: :::::::::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| @:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| ::@@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
| : @@:: ::: : :::: ::@:@ ::: :: :::: @ :: ::: ::::::# ::::@: ::@::::::::
0 +----------------------------------------------------------------------->Gi
0 1.030
The details are stored in the file, inside different tables.
To fully understand the output refers to the Valgrind manual page which seems really clear.
The option to trace the children is: --trace-children=yes
Interesting, it seems that there is no "actual memory usage of a process":
https://unix.stackexchange.com/questions/164653/actual-memory-usage-of-a-process.
Profile per-function memory usage in C in Unix
As OP highlighted, each class of storage can be measured with different tool. In the old
days (C90), this was relativel simple. Nowadays, much more complex ...
Static Memory:
Static memory (static or global), can be measured at the object file level (.o) using the size
tool. This will include the memory for all static data in the file - potentially multiple functions. For example the function in o5 need 120+512 (data+bss)
size o5.o
text data bss dec hex filename
757 512 120 1389 56d o5.o
Automatic Variables
Measuring automatic variables ("local") is more tricky. Before C99, allocation was fixed at compiled time (with the exception of the now alloca
calls). It was possible to inspect the assembly generated code to find out how much stack space is allocated for a function. With C99, which allows VLA, this is no longer possible, for example
void f(int n) {
int a[n+3] ; // Variable Length Array, size calculated at run time.
}
Also, with optimizations, many compiler are able to detect that two variables can share the same space, as they are not used at the same time. For example, most compilers can tell that x and y can share the same space.
void f(int n) {
for (int i=0 ; ... ; ... ) {
int x[30] ;
} ;
for (int j=0 ; ... ; ... ) {
int y[30] ;
} ;
}
In theory, one can sample the stack size during run time, and try to determine 'typical' size of a function with VLA. For functions without VLA, ofter possible to extract the data from the generated assembly. Mileage will vary.
Dynamic Variables
For Dynamic memory allocations (malloc, and friends) - runtime tool are best set to capture how much memory is allocated. However, most tools will not be able to measure actual dynamic usage - they will usually perform analysis of the heap at a specific point of time, which could be more or less than what the function is actually using.
profiling maximum memory usage in C application - linux
Take a look at Massif: http://valgrind.org/docs/manual/ms-manual.html
How to profile memory usage of a C program
You could wrap all your calls to free
and malloc
with your own functions in which you also supply for instance in which file and at what line number each allocation is done. From this information it's easy to see what memory is being used where.
Is it possible to profile memory only by storing allocated pointer address in C++?
Is it true, that in C++ I can be sure that pointer passed to the operator delete (or free()) always will be the one previously allocated?
Yes, this is true. It could also be a null pointer, in which case your function should do nothing.
The behavior of the standard library implementation of this function is undefined unless ptr is a null pointer or is a pointer previously obtained from the standard library implementation of
operator new
...
Since most code is written for the standard library implementation of operator new
/delete
, it does not pass other pointers to operator delete
.
It is possible for someone to write a class with an overloaded operator new
and operator delete
which do not have this requirement. In that case, it won't call your custom allocator, either.
Related Topics
Can Branches with Undefined Behavior Be Assumed Unreachable and Optimized as Dead Code
How to Use Dylib in MAC Os X (C++)
What Is the Size of an Enum Type Data in C++
Efficiently Reading a Very Large Text File in C++
Int *Array = New Int[N]; What Is This Function Actually Doing
Acquire/Release Semantics with 4 Threads
How to Ensure Constexpr Function Never Called at Runtime
What Is the Ascii Value of Eof in C
Fastest Way to Get the Integer Part of Sqrt(N)
When Does Move Constructor Get Called
C++ Trying to Swap Values in a Vector
C++ #Include and #Import Difference
Constructor Initialization VS Assignment
C++ Template Metaprogramming - How to Output the Generated Code