Process Growth with Railsbench's GC patch

Eric Hodel | Tue, 17 Apr 2007 19:57:00 GMT

Posted in , ,

My friend Kevin Watt who runs Allpoetry had me help him diagnose problems with memory consumption on his Rails application. He was seeing processes suddenly jump in size by 46MB, when the processes were already over 100MB to begin with. After instrumenting to locate the growth in one innocuous method we went through his patches to Rails.

One of the patches Kevin was using was the Railsbench GC patch. It turns out that this patch has some very useful instrumenting of its own, so I had Kevin call GC.dump in that method, and he got the following values:

HEAP[ 0]: size= 650000
HEAP[ 1]: size=1170001

This means there are slots for 1820001 objects in his process. If you end up creating that many objects Ruby will create a new chunk of object slots by multiplying the previous allocation by 1.8 and adding 1.

The next set of slots would contain slots for 2106002 objects. Each slot takes up 20 bytes of memory, so roughly 40MB of memory would be used. Kevin ended up pulling the patch and now has his processes holding on to around 70MB RSS each, rather than 100 or more.

The Railsbench page contains this note about memory consumption alongside the GC patch:

In addition, a patch for the ruby garbage collector is provided, which can be used to reduce the amount of time spent doing garbage collection, trading memory for speed, as usual (see file GCPATCH for details).

The initial size of the slots can be tuned, but we neglected to explore that option. In large-memory situations the patch's behavior is too negative. Be sure to follow the instructions to the GCPATCH file to get proper operation. Also, monitor your application's memory usage as the patch may cause your machine to use swap when too many objects are being used or if you've tuned improperly. 2 comments

Comments RSS FEED

The patch doesn’t change the GC algorithm. If you don’t set any of the environment variables, you will get exactly the same behavior as with an unpatched Ruby. I’d suggest to start with a smaller initial heap size, or, even better, use railsbench perf_run_gc with a few benchmarks to find out the heap size you need.

The patch doesn’t cause swapping, choosing the wrong initial heap size does.

Stefan Kaes said 10 days later

Just the same, the more you increase the initial heap size, the more likely you are to have extremely negative behavior when you have “too many” objects.

Eric Hodel said 13 days later

Comments are disabled