Compacting GC doesn't attempt to improve block-level fragmentation
The compacting GC removes unused space within blocks but not unused space within megablocks.
Unfortunately this doesn't help fragmentation issues very much, here are some histograms to demonstrate the problem. Both are after compacting GC has run. Histograms are generated using ghc-debug
.
This a "percentage block filled" histogram which indicates that after compacting most blocks are nearly 100% filled. That's good.
0.0%-10.0%: 52
10.0%-20.0%: 13
20.0%-30.0%: 6
30.0%-40.0%: 8
40.0%-50.0%: 4
50.0%-60.0%: 3
60.0%-70.0%: 8
70.0%-80.0%: 11
80.0%-90.0%: 17
90.0%-100.0%: 6959
150.0%-160.0%: 1
190.0%-200.0%: 27
200.0%-210.0%: 2
Then just looking at the blocks which are > 90% filled, how full are the megablocks which they live in?
0.0%-10.0%: 133
10.0%-20.0%: 6
20.0%-30.0%: 1
30.0%-40.0%: 4
40.0%-50.0%: 2
50.0%-60.0%: 4
60.0%-70.0%: 7
70.0%-80.0%: 7
80.0%-90.0%: 5
90.0%-100.0%: 6
This is quite bad because the majority of megablocks are quite empty so the heap is still quite fragmented.
It would perhaps be better if the compacting GC would also attempt to compact into MBlocks as well as into blocks. One way to achieve this would be to allocate into fresh blocks when compacting rather than reusing old blocks.