Ubuntu System Monitor and valgrind to discover memory leaks in C++ applications
Another tool you can try is the /lib/libmemusage.so
library:
$ LD_PRELOAD=/lib/libmemusage.so vim
Memory usage summary: heap total: 4643025, heap peak: 997580, stack peak: 26160
total calls total memory failed calls
malloc| 42346 4528378 0
realloc| 52 7988 0 (nomove:26, dec:0, free:0)
calloc| 34 106659 0
free| 28622 3720100
Histogram for block sizes:
0-15 14226 33% ==================================================
16-31 8618 20% ==============================
32-47 1433 3% =====
48-63 4174 9% ==============
64-79 4736 11% ================
80-95 313 <1% =
...
(I quit vim
immediately after startup.)
Maybe the histogram of block sizes will give you enough information to tell where leaks may be happening.
valgrind
is very configurable; --leak-check=full --show-reachable=yes
might be a good starting point, if you haven't tried it yet.
"Virtual Memory", "Resident Memory", "Writable Memory" and "Memory"
Virtual memory is the address space that your application has allocated. If you run malloc(1024*1024*100);
, the malloc(3)
library function will request 100 megabytes of storage from the operating system (or handle it out of the free lists). The 100 megabytes will be allocated with mmap(..., MAP_ANONYMOUS)
, which won't actually allocate any memory. (See the rant at the end of the malloc(3)
page for details.) The OS will provide memory the first time each page is written.
Virtual memory accounts for all the libraries and executable objects that are mapped into your process, as well as your stack space.
Resident memory is the amount of memory that is actually in RAM. You might link against the entire 1.5 megabyte C library, but only use the 100k (wild guess) of the library required to support the Standard IO interface. The rest of the library will be demand paged in from disk when it is needed. Or, if your system is under memory pressure and some less-recently-used data is paged out to swap, it will no longer count against Resident memory.
Writable memory is the amount of address space that your process has allocated with write privileges. (Check the output of pmap(1)
command: pmap $$
for the shell, for example, to see which pages are mapped to which files, anonymous space, the stack, and the privileges on those pages.) This is a reasonable indication of how much swap space the program might require in a worst-case swapping scenario, when everything must be paged to disk, or how much memory the process is using for itself.
Because there are probably 50--100 processes on your system at a time, and almost all of them are linked against the standard C library, all the processes get to share the read-only memory mappings for the library. (They also get to share all the copy-on-write private writable mappings for any files opened with mmap(..., MAP_PRIVATE|PROT_WRITE)
, until the process writes to the memory.) The top(1)
tool will report the amount of memory that can be shared among processes in the SHR
column. (Note that the memory might not be shared, but some of it (libc
) definitely is shared.)
Memory is very vague. I don't know what it means.
How I can detect memory leaks of C++ application in Linux (Ubuntu OS)?
Check out Valgrind, it should be in the Ubuntu repository. it can give you detailed information about memory usage in C++ programs. Kind of like a debugger for memory usage.
valgrind --tool=memcheck <your_app> <your_apps_params>
Can using Valgrind on Linux also help when the app is compiled on Solaris?
Generally speaking, if the code execution path is the same on both systems and you clean up the memory leaks on one then yes, it will clean them up on the other system too.
It's not quite so straight forward when things differ between the machines though. EG, it tries to do one thing on the linux system and another thing on the solaris system.
Valgrind is a great tool and the best thing to do is try it on linux and see if it cleans up the leaks on solaris too (check with ps or another tool that lists the memory size under solaris and make sure it doesn't increase there).
How to find memory leak in a C++ code/project?
Instructions
Things You'll Need
- Proficiency in C++
- C++ compiler
- Debugger and other investigative software tools
1
Understand the operator basics. The C++ operator new
allocates heap memory. The delete
operator frees heap memory. For every new
, you should use a delete
so that you free the same memory you allocated:
char* str = new char [30]; // Allocate 30 bytes to house a string.
delete [] str; // Clear those 30 bytes and make str point nowhere.
2
Reallocate memory only if you've deleted. In the code below, str
acquires a new address with the second allocation. The first address is lost irretrievably, and so are the 30 bytes that it pointed to. Now they're impossible to free, and you have a memory leak:
char* str = new char [30]; // Give str a memory address.
// delete [] str; // Remove the first comment marking in this line to correct.
str = new char [60]; /* Give str another memory address with
the first one gone forever.*/
delete [] str; // This deletes the 60 bytes, not just the first 30.
3
Watch those pointer assignments. Every dynamic variable (allocated memory on the heap) needs to be associated with a pointer. When a dynamic variable becomes disassociated from its pointer(s), it becomes impossible to erase. Again, this results in a memory leak:
char* str1 = new char [30];
char* str2 = new char [40];
strcpy(str1, "Memory leak");
str2 = str1; // Bad! Now the 40 bytes are impossible to free.
delete [] str2; // This deletes the 30 bytes.
delete [] str1; // Possible access violation. What a disaster!
4
Be careful with local pointers. A pointer you declare in a function is allocated on the stack, but the dynamic variable it points to is allocated on the heap. If you don't delete it, it will persist after the program exits from the function:
void Leak(int x){
char* p = new char [x];
// delete [] p; // Remove the first comment marking to correct.
}
5
Pay attention to the square braces after "delete." Use delete
by itself to free a single object. Use delete []
with square brackets to free a heap array. Don't do something like this:
char* one = new char;
delete [] one; // Wrong
char* many = new char [30];
delete many; // Wrong!
6
If the leak yet allowed - I'm usually seeking it with deleaker (check it here: http://deleaker.com).
Valgrind on ARMv5
Valgrind is a very powerful tool and it's pretty sad that it does not work on ARMv5 because it makes debugging memory leaks and invalid memory accesses more difficult on this platform.
I see several less powerful options. You can try to enable some additional checks within the C library by setting the MALLOC_CHECK_ environment variable. If your compiler is GCC 4.8 or higher you can try AddressSanitizer (I never used it on ARMv5 though).
Memory leak detectors for C?
second the valgrind... and I'll add electric fence.
Analysing resource leaks in network applications (socket handlers etc)
Valgrind has the ability to track a few of the resources you are interested in:
Memory via memcheck
File descriptors via the
--track-fds=yes
memcheck optionThreads and locks via Helgrind and DRD
The generated information is not always detailed, but it can be quite helpful.
Related Topics
Copy Constructor of Derived Qt Class
Std::Istream_Iterator<> with Copy_N() and Friends
Behaviour of Negative Zero (-0.0) in Comparison with Positive Zero (+0.0)
How Is Push_Back Implemented in Stl Vector
How Could I Sensibly Overload Placement Operator New
How to Analyze Program Running Time
How to Share Memory Between Linux Program and Windows Program Running Through Wine (Same Computer)
Best C++ Development Environment in Linux
Unresolved Externals Despite Linking in Zlib.Lib
Static Initialization and Destruction of a Static Library's Globals Not Happening with G++
What Happens to an Stl Iterator After Erasing It in VS, Unix/Linux
Adding Quotes to Argument in C++ Preprocessor
Function Template Specialization Importance and Necessity