DHAT: a dynamic heap analysis tool
perform such an analysis. We can see that they must have varying sizes since the average block size, 61.13, isn’t a
whole number.
10.2.2.2. A more suspicious looking example
max-live:
180,224 in 22 blocks
tot-alloc:
180,224 in 22 blocks (avg size 8192.00)
deaths:
none (none of these blocks were freed)
acc-ratios:
0.00 rd, 0.00 wr
(0 b-read, 0 b-written)
at 0x4C275B8: malloc (vg_replace_malloc.c:236)
by 0x40350E: tcc_malloc (tinycc.c:6712)
by 0x40369C: __sym_malloc (tinycc.c:6787)
by 0x403711: sym_malloc (tinycc.c:6805)
Here, both the read and write access ratios are zero.
Hence this point is allocating blocks which are never used,
neither read nor written. Indeed, they are also not freed ("deaths: none") and are simply leaked. So, here is 180k of
completely useless allocation that could be removed.
Re-running with Memcheck does indeed report the same leak. What DHAT can tell us, that Memcheck can’t, is that
not only are the blocks leaked, they are also never used.
10.2.2.3. Another suspicious example
Here’s one where blocks are allocated, written to, but never read from. We see this immediately from the zero read
access ratio. They do get freed, though:
max-live:
54 in 3 blocks
tot-alloc:
1,620 in 90 blocks (avg size 18.00)
deaths:
90, at avg age 34,558,236
acc-ratios:
0.00 rd, 1.11 wr
(0 b-read, 1,800 b-written)
at 0x4C275B8: malloc (vg_replace_malloc.c:236)
by 0x40350E: tcc_malloc (tinycc.c:6712)
by 0x4035BD: tcc_strdup (tinycc.c:6750)
by 0x41FEBB: tcc_add_sysinclude_path (tinycc.c:20931)
In the previous two examples, it is easy to see blocks that are never written to, or never read from, or some combination
of both. Unfortunately, in C++ code, the situation is less clear. That’s because an object’s constructor will write to
the underlying block, and its destructor will read from it. So the block’s read and write ratios will be non-zero even if
the object, once constructed, is never used, but only eventually destructed.
Really, what we want is to measure only memory accesses in between the end of an object’s construction and the start
of its destruction. Unfortunately I do not know of a reliable way to determine when those transitions are made.
10.2.3. Interpreting "Aggregated access counts by
offset" data
For allocation points that always allocate blocks of the same size, and which are 4096 bytes or smaller, DHAT counts
accesses per offset, for example:
152