Who wants to have some fun memory debugging?

Daniel Keep daniel.keep.lists at gmail.com
Tue May 12 23:44:29 PDT 2009



Sean Kelly wrote:
> ...
> 
> At this point it's quite possible that you still have a reference to
> newData in a register.  If you want to be sure the collect call below
> works as intended for this test, try adding:
> 
>           newData = new Data;
> 
> here.

Debugging it with ddbg under Win XP, I found that at "data = null",
there is what appears to be a pointer to the newest allocation in EDX,
and a pointer to the previous one in ECX.

>>         i = 0;

After this line, the ECX reference hasn't been touched.

>>         GC.collect();

Disassembling the code, there's nothing that touches ECX before the call
to GC.collect, so it's quite probable that this is why the memory isn't
being freed in a given iteration, but not necessarily why it isn't being
collected at all.

I modified the code to explicitly zero-out ECX just before the call to
GC.collect, and it didn't appear to help.

I then instrumented the code with calls to gc_stats.  Here is the run of
it reporting the stats AFTER each forced collect (output via printf):

GCStats: poolsize, usedsize, freeblocks, freelistsize, pageblocks
GCStats: 81985536, 640, 16, 7552, 9999
GCStats: 163840000, 640, 3200, 7552, 18399
GCStats: 232652800, 640, 2030, 7552, 27384
GCStats: 306315264, 640, 5948, 7552, 34417
GCStats: 360251392, 640, 6954, 7552, 40498
GCStats: 410517504, 640, 5502, 7552, 47360
GCStats: 469958656, 640, 8498, 7552, 53118

The program also got progressively slower as the size of the heap
increased.  Odd thing is that it would pause at a certain heap size for
many seconds at a time, increase in size, pause, increase, pause... it
was like the allocations were getting slower.

What's also weird is that even though the heap usage should be the same
each iteration, it's clearly creating more and more blocks.  It's like
the GC is freeing those blocks, but the allocator isn't using them.

Then I ran it so that it would compute the difference of gc_stats before
and after the collect.  This one is somewhat depressing:

GCStats: poolsize, usedsize, freeblocks, freelistsize, pageblocks
GCStats: 0, 0, 2, 0, -1
GCStats: 0, 0, 2, 0, -1
GCStats: 0, 0, 2, 0, -1
GCStats: 0, 0, 2, 0, -1
GCStats: 0, 0, 2, 0, -1
GCStats: 0, 0, 2, 0, -1

It appears to free *two* blocks and consume an extra page during a
collection, but doesn't affect the pool or used size at all.

Maybe it's time to put together an instrumented GC...

  -- Daniel


More information about the Digitalmars-d-learn mailing list