This page details some changes to the ruby garbage collector which seem to afford a 25% reduction in maximum heap memory usage, and nearly double the amount of heap space ruby’s is able to reclaim. This comes at the cost of a 2% performance hit. More to come, stay tuned.
patch
The latest patch to ruby 1.8.6 is available here.
summary of changes
- Fixed 2k heaps
- Heap implementation broken into separate c/h file
- heaps stored sorted by address for efficient is_pointer_to_heap()
- “adaptive GC frequency” – perform GC more frequently when free percentage is high.
testing strategy
To test changes, I’m comparing the performance of a handful of tests (most contributed by Hugh Sasse, many thanks!). Ruby 1.8.6 unpatched is run over these tests, then compared against the performance of ruby 1.8.6 with my patch. In order to get “maximum heap size”, “current heap size”, and “nmber of gc passes”, a GC.heap_info function has been hacked in to both.
NOTE: When referring to heap size, we’re really talking about the amount of memory dedicated to ruby heaps, not the total heap usage of the ruby process.
finally, all tests are performed on a macbook dual core with 2 gigs of RAM. We use wallclock time, but I’ve ensured an idle machine and rerun tests to verify that system load doesn’t significantly affect results.
data
test before after difference time gc max mem final mem time gc max mem final mem time gc max / final mem weak_hashes_read.rb 0.459 8 4473980 4473980 0.448 9 2570240 2570240 97% 112% 57% 57% create_hashes_yaml.rb 25.91 75 27300060 8253120 26.43 75 18012160 614400 102% 100% 65% 7% create_hashes.rb 0.134 4 1208000 560000 0.142 6 1077248 75776 105% 150% 89% 13% arrays_read_yaml.rb 0.760 14 4473980 4473980 0.753 13 3278848 3278848 99% 92% 73% 73% ostruct_read.rb 2.643 19 15055440 15055440 2.866 22 8781824 8781824 108% 115% 58% 58% create_ostructs_yaml.rb13.67 55 27299780 15055440 14.47 57 15616000 9125888 105% 103% 57% 60% classes_read_yaml.rb 0.825 13 4473940 4473940 0.850 13 4151296 4149248 102% 100% 92% 92% create_weak_hashes2.rb 0.497 7 4473940 4473940 0.512 9 2643968 2490368 102% 128% 59% 55% create_arrays_yaml.rb 9.003 43 15055660 8253140 9.169 44 9859072 2252800 101% 102% 65% 27% create_arrays.rb 0.171 4 2374420 560000 0.179 6 1912832 75776 104% 150% 80% 13% growarray.rb 1.933 9 200000 200000 2.116 9 102400 75776 109% 100% 51% 37% arrays_read.rb 0.089 4 2374460 560000 0.0922 5 1679360 73728 103% 125% 70% 13% hashes_read_yaml.rb 1.982 23 4473920 4473920 1.908 20 4532224 4532224 96% 86% 101% 101% plist.rb 4.926 23 15055760 15055760 4.773 18 12734464 10463232 96% 78% 84% 69% create_ostructs.rb 3.077 22 15055660 11276480 3.284 24 8800256 92160 106% 109% 58% 0% create_weak_hashes.rb 1.206 17 4473960 4473960 1.132 14 5253120 4933632 93% 82% 117% 110% classes_read.rb 0.057 3 1208000 1208000 0.063 5 919552 919552 110% 166% 76% 76% shrinkarray.rb 1.932 9 200000 200000 2.1230 9 100352 77824 109% 100% 50% 38% ostruct_read_yaml.rb 1.143 20 2374400 2374400 1.114 17 3178496 3178496 97% 85% 133% 133% hashes_read.rb 0.052 3 1208000 1208000 0.052 4 876544 876544 100% 133% 72% 72% overall: 102% 110% 75% 55%
feedback
Send feedback to lloyd 4t trickyco.de