From: Lloyd Hilaiel Date: 2007-11-02T04:09:53+09:00 Subject: hacking on the "heap" implementation in gc.c Hi all, I've been playing (and that's all it is at this point) with the heap implementation in gc.c. In practice the behavior I see with ruby 1.8 today is that the heaps grow, but do not shrink. My theory was that large heaps are bad, because they make it impossible to ever reclaim heap space (in fork case, or programs that do a lot of processing, then calm down, i.e. PList parsing). A large heap is bad because of the scanning we do. All pages must be resident and private (copy on write). I know some folks are looking at addressing the copy on write issues with external storage of mark bits. I'm hoping that some more fundamental changes which decrease memory usage without affecting performance may offer benefits which are valuable with or without moving gc mark bits out of the heap. So the changes I've made are: 1. break heap implementation out from gc.c into heap.c and heap.h 2. reduce heap size to 0x400 bytes 3. optimize common operations on heaps to repair performance. Once the above is done, it's no longer meaningful to say "do GC once before we add a heap", because heaps are tiny. So instead I've a simple heuristic in newobj that says, "perform next garbage collection when the number of slots used rises to 180%". (preserving the magic number of 1.8, at least in spirit. Finally, I'm experimenting with having this magic number be adaptive based on the fragmentation of the heap (% free). so it's 1.2 + (1 - (%free/ 100)). if 50% of the heap is in use, we'll GC again at 170%, if 20% is free, we'll wait till the slots used doubles. The idea here is that the more fragmented the heap the higher the potential that we can reclaim space (compact) by running GC more frequently. On average, approximately the same number of GCs are done in a run as with upatched 1.8.6, they are just done at different times which seems to be a good thing so far... Some preliminary results and my patches are available here: http://lloydforge.org/projects/ruby What I would love is criticism on the approach, and some performance testing of this patch to see if the gains I'm seeing are artificial. This patch is just a proof of concept and play, many things would need to be cleaned up before it would be something that could be useful (RUBY_CRITICAL being one thing of many). hope this is interesting, lloyd