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