我对Rails应用程序的红宝石。 我调查我的门户NewRelic的一个Apdex的下降,我看到,平均而言,时间250-320ms花费在GC执行。 这是一个非常令人不安数。 以下附上拍摄的画面。
我的红宝石版本是:
红宝石1.9.3p194(2012-04-20的修订35410)[x86_64的Linux的]
对于这种调整任何建议将是理想的。 此数目应明显较低。
我对Rails应用程序的红宝石。 我调查我的门户NewRelic的一个Apdex的下降,我看到,平均而言,时间250-320ms花费在GC执行。 这是一个非常令人不安数。 以下附上拍摄的画面。
我的红宝石版本是:
红宝石1.9.3p194(2012-04-20的修订35410)[x86_64的Linux的]
对于这种调整任何建议将是理想的。 此数目应明显较低。
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.
您应该使用分配的示踪剂,找出你的代码分配对象,以及有多少。 我用memprof
在很大的成绩了过去......大缺点是,它只有1.8红宝石下工作(希望你的代码是1.8.7兼容)。
如果你可以的Ruby 1.8.7下运行你的应用程序,然后安装“memprof”的宝石,并且:
require 'memprof'
GC.disable
Memprof.track { run_test_code_here }
这将打印分配的对象计数到标准输出(均由类和源极线上的分配发生的位置分组)的列表。
当你花费在垃圾收集过多的时间问题,通常的分配跟踪显示一个或两个地方,你的程序是分配万吨对象。 这是不可能事先说的解决方案将是什么,但往往会涉及到两种:
map!
而不是map
), 还有这个小黑客 ,这可能工作。 但是,更大的应用程序往往分配,你杀了每个请求工人如此大量的内存: - /
假设你没有创建错误不需要的对象,我听到一个黑客/解决方案(除了使用JRuby)是强制GC完成发送响应后。 这样,你有很大的停顿,但它没有被请求的消费者看到。 如果你有这么多垃圾,你看到多个停顿这样,那么你可能是出于运气。
这一招可能会或可能不会对你的工作需要。
-JRuby家伙谁说话的人与MRI GC问题:)