OVERVIEW:
Heap-buddy is a heap profiler for mono. It attaches to special hooks in the
mono runtime and tracks all of the managed memory allocations, every garbage
collection and every heap resize. These statistics are written out into a
data file that we call an 'outfile'.
INSTALLING HEAP-BUDDY:
./configure; make; make install from a tarball
./autogen.sh; make; make install from SVN
The mono runtime will not find the heap-buddy plug-in unless you install it
into a prefix that is in your LD_LIBRARY_PATH.
GENERATING OUTFILES:
mono --profile=heap-buddy foo.exe writes the alloc data to ./outfile
mono --profile=heap-buddy:/foo/bar foo.exe writes the alloc data to /foo/bar
PRODUCING STATISTICS FROM OUTFILES:
Heap-buddy can currently generate four reports about your program's memory
usage. The program that produces the reports is also called heap-buddy. The
general form of a heap-buddy command-line is:
% heap-buddy <outfile name> <report name> <arguments>
If you omit the outfile name, it defaults to 'outfile'. If you omit the
report name, it defaults to the summary report.
(1) Summary Report
This report prints some basic high-level information about that run's
allocations. It does not take any arguments.
% heap-buddy outfile.beagled summary
SUMMARY
Filename: outfile.beagled
Allocated Bytes: 131.8M
Allocated Objects: 2238291
GCs: 74
Resizes: 16
Final heap size: 17.6M
Distinct Types: 418
Backtraces: 29141
(2) GC/Resize History
This report prints information about every GC and heap resize. It does
not take any arguments.
20:59:13 | Init | Initialized heap to 128k
| |
20:59:13 | Resize | Grew heap from 128k to 192k
| | 4.0k in live objects
| | Heap went from 3.2% to 2.1% capacity
| |
20:59:13 | Resize | Grew heap from 192k to 268k
| | 40k in live objects
| | Heap went from 20.8% to 14.9% capacity
| |
20:59:13 | GC 0 | Collected 630 of 1407 objects (44.8%)
| | Collected 24k of 83k (29.0%)
| | Heap went from 31.2% to 22.2% capacity
(etc.)
(3) Statistics by Type
This report tells you about how many objects of each type were instantiated,
and how much memory was consumed. By default, it prints the 25 types that
consumed the most bytes in memory.
% heap-buddy outfile.beagled types
Type # Total AvSz AvAge BT#
byte[] 68280 57.7M 886.5 0.0 432
string 666060 34.8M 54.8 0.4 4953
char[] 42677 10.1M 249.4 0.1 267
System.Text.StringBuilder 139524 3.2M 24.0 0.0 784
int 243299 2.8M 12.0 0.0 346
(etc.)
Heap-buddy features the patent-pending Elizatron 2000(tm) natural language
command-line interface. Instead of having to use cryptic, hard-to-remember
command line arguments (i.e. "heap-buddy -x -q -iii --frobnicate-goats 47"),
you simply talk to the computer the way you might address to a small child or
intelligent dog who has a freakish, savant-like understanding of garbage
collection. Valid heap-buddy command lines include:
heap-buddy types sorted by average age
heap-buddy types 50 sorted by count and make it snappy
heap-buddy types and please show me the full names
heap-buddy types all matching System.Xml and sort them by average size
Using a low-level development tool has never been more fun!
(4) Statistics by Backtrace
This report produces statistics similar to the type report, but it tells you
exactly where each allocation occurred.
% heap-buddy outfile.beagled backtraces
Backtrace # Total AvSz AvAge
type=byte[] 1208 10.4M 9069.2 1.1
System.IO.MemoryStream:set_Capacity
System.IO.MemoryStream:Write
GMime.Stream:CopyToStream
GMime.Object:WriteToStream
Beagle.Daemon.Evolution...GMimeMessageToIndexable
Beagle.Daemon.Evolution...orMbox:GetNextIndexable
AddGeneratorTask:DoTaskReal
Task:DoTask
Beagle.Util.Scheduler:Worker
type=byte[] 1208 10.4M 9069.2 0.0
GMime.Stream:CopyToStream
GMime.Object:WriteToStream
Beagle.Daemon.Evolution...GMimeMessageToIndexable
Beagle.Daemon.Evolution...orMbox:GetNextIndexable
AddGeneratorTask:DoTaskReal
Task:DoTask
Beagle.Util.Scheduler:Worker
(etc.)
You can also use Elizatron 2000(tm)-style arguments with this report.
KNOWN BUGS/ISSUES:
Heap-buddy is not smart about recursive programs. If you have a recursive
function that contains allocations, each level of recursion will generate a
distinct backtrace. This produces extremely large outfiles and
difficult-to-read reports. (This is fixable, but requires adding code to the
runtime plug-in to intelligently detect cycles in backtraces.)
Some misguided people think that the natural language interface is silly.
LICENSE:
The code is licensed under the terms of the MIT X11 license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.