Hacker News new | ask | show | jobs
by z92 2374 days ago
The compaction GC was the most important change. I haven't measured Ruby's performance specifically but in general the difference and improvements over a non-compacting GC is so huge. Specially for long running processes.
2 comments

Its an important change, but not huge, at least not yet: it's not yet integrated in the GC, which means you have to explicitly request it. And most of the fragmentation comes anyway from the allocations heap. That being said, I think this will improve in the coming releases.
What criteria should be monitored to request compaction in a long-running process? Is a timer sufficient (at what interval?) or are there other tools available in Ruby to make that decision?
It's likely to be most useful for anyone using a Unicorn-style process forking model in Ruby.

You call `GC.compact` in the parent right before forking off your child processes and because the memory in the children are copy-on-write (COW), it lets them share memory with their parent far longer than they normally would be able to.

Any change in a page (i.e. an object allocated or deallocated) causes it to be copied to a child process, and because previously pages were a mix of objects of all kinds of longevity and slots which may be empty or used, children tended to copy their parent's entire memory space very quickly. Running a GC and compact before forks improves the likelihood that shared pages are mostly full of still-in-use, longer-lived objects, and gives the COW strategy a fighting chance.

>over a non-compacting GC is so huge

Yes in other languages, but as far as I am aware that is not the case in Ruby ( Specific to Rails ) . At least I wouldn't use so huge to describe the improvement.