Ruby GC execution exceeding ~250-320ms per request

前端 未结 4 2027
暗喜
暗喜 2021-02-04 09:18

I have a ruby on rails application. I am investigating an Apdex decline in my NewRelic portal and I\'m seeing that on average, 250-320ms of time is being spent on GC execution.

4条回答
  •  花落未央
    2021-02-04 09:57

    You're spending so much time in GC because you're running your GC so often. Ruby, by default, sets GC parameters that are appropriate for small scripts, not large apps. Try launching your app with the following environment parameters set:

    RUBY_HEAP_MIN_SLOTS=800000
    RUBY_FREE_MIN=100000
    RUBY_GC_MALLOC_LIMIT=79000000
    

    What this'll do is increase the initial heap allocation size and pad the GC numbers so that it doesn't run quite so often. This may let your app use a bit more RAM, but it should reduce the time spent in GC dramatically. Under the default settings, you're likely running GC multiple times per request; you want to be ideally be running it once every few requests (or even better, between requests with something like Unicorn's OOB::GC).

    Those are my GC settings for my app, and you'll want to tweak them up and down as is most appropriate for your app to find the right settings; you're gunning for a middle ground where you aren't running GC so often, and don't have excessive memory usage. This is specific to each app, though, so there's no boilerplate advice I can give on what those exact settings should be. Increasing from the defaults (10k slots, 1.8x growth factor) should have an immediate impact, and you can tweak up and down from there as best fits your current situtation.

    There's a full writup of these parameters here and more information here, and while those posts were written for REE 1.8.7, they're applicable to Ruby 1.9.2+ as well.

    Those are some rather extreme numbers, so it's possible that you're doing something in your app that is causing you to allocate much more RAM than you should, so I'd encourage you to be suspicious and comb through your app looking for over-eager allocations. The GC environment variables should help triage the situation in any case, though.

提交回复
热议问题