jfr*_*prr 11 ruby memory-management ruby-on-rails ruby-on-rails-3
我们一直试图找出如何通过识别内存饥渴的宝石并寻找替代方案或解决方案来减少我们的rails应用程序的启动内存占用.
但是OS X上有一个我觉得困惑的行为.
使用全新生成的rails app(rails new memoryusage),没有Gemfile,没有模型,没有数据和没有事务,在启动rails c内存OSX显示相应的ruby进程时,每次启动时都会有所不同,从低至60MB到高达65MB,没有可辨别的模式,为什么同一个应用程序可能需要每次执行更少或更多的内存.
我想这必须以某种方式来处理Ruby如何分配内存,但我并不完全清楚为什么它的内存分配会因为相同的代码和变量处理而变化太大.
当我们尝试在Gemfile中的每个gem之后计算进程消耗的内存时,我们有类似的不可预测的行为.我们加载一个vanilla rails进程,然后在rails c我们运行一个解析Gemfile的脚本并分别需要每个Gem,记录需求前后的内存,我们注意到内存占用不仅没有一致性起点,但我们的记忆消耗中的渐进"步骤"变化很大.
我们一个接一个地启动我们的进程三次,并测量每个gem所需的启动内存和增量内存.启动书的记忆足迹不仅在60MB到92MB之间反弹,而且我们在加载每个宝石时看到内存跳跃的点是不一致的 - 有时加载SASS会额外消耗掉 5MB,有时它不会,有时会活跃_merchant会需要额外增加10MB,其他则不需要.
: BOOT UP #1 : BOOT UP #2 : BOOT UP #3
gem : increment | total : increment | total : increment | total
rails : 0.00 | 59.71 : 0.00 | 92.54 : 0.18 | 67.76
unicorn : 0.52 | 60.24 : 0.52 | 93.06 : 3.35 | 71.12
haml : 8.77 | 69.02 : 1.88 | 94.94 : 9.45 | 80.57
haml-rails : 0.00 | 69.02 : 0.00 | 94.94 : 0.00 | 80.57
sass : 4.36 | 73.38 : 6.95 | 101.89 : 0.99 | 81.55
mongoid : 0.00 | 73.38 : 0.00 | 101.89 : 0.00 | 81.55
compass : 11.56 | 84.93 : 3.23 | 105.12 : 8.41 | 89.96
compass-rails : 0.00 | 84.93 : 0.08 | 105.20 : 0.00 | 89.96
compass_twitter_bootstrap: 0.00 | 84.93 : 0.00 | 105.20 : 0.00 | 89.96
profanalyzer : 0.59 | 85.52 : 0.46 | 105.66 : 0.64 | 90.60
simple_form : 0.34 | 85.87 : 0.35 | 106.01 : 0.00 | 90.60
sorcery : 0.00 | 85.87 : 0.25 | 106.26 : 1.07 | 91.67
validates_timeliness: 1.47 | 87.34 : 1.82 | 108.07 : 1.62 | 93.29
mongoid_token : 0.00 | 87.34 : 0.00 | 108.07 : 0.00 | 93.29
nested_form : 0.00 | 87.34 : 0.00 | 108.07 : 0.01 | 93.30
nokogiri : 0.86 | 88.20 : 1.16 | 109.24 : 1.37 | 94.67
carmen : 0.00 | 88.20 : 0.07 | 109.30 : 0.00 | 94.67
carrierwave/mongoid : 2.78 | 90.98 : 0.38 | 109.69 : 0.13 | 94.80
yajl : 0.04 | 91.02 : 0.04 | 109.73 : 0.04 | 94.84
multi_json : 0.00 | 91.02 : 0.00 | 109.73 : 0.00 | 94.84
uuid : 0.00 | 91.03 : 0.00 | 109.73 : 0.41 | 95.25
tilt : 0.00 | 91.03 : 0.00 | 109.73 : 0.00 | 95.25
dynamic_form : 0.00 | 91.04 : 0.00 | 109.73 : 0.00 | 95.25
forem : 0.03 | 91.07 : 0.00 | 109.73 : 0.00 | 95.25
browser : 0.00 | 91.07 : 0.00 | 109.73 : 0.00 | 95.25
activemerchant : 2.17 | 93.24 : 1.18 | 110.92 : 10.58 | 105.83
kaminari : 0.00 | 93.24 : 0.00 | 110.92 : 0.00 | 105.83
merit : 0.00 | 93.24 : 0.00 | 110.92 : 0.00 | 105.83
memcachier : 0.00 | 93.24 : 0.00 | 110.92 : 0.00 | 105.83
dalli : 0.01 | 93.25 : 0.05 | 110.96 : 0.34 | 106.17
bitly : 2.47 | 95.72 : 9.43 | 120.40 : 1.53 | 107.70
em-synchrony : 1.00 | 96.72 : 0.18 | 120.57 : 0.55 | 108.24
em-http-request : 5.56 | 102.28 : 2.15 | 122.72 : 1.40 | 109.64
httparty : 0.00 | 102.28 : 0.00 | 122.72 : 0.00 | 109.64
rack-block : 0.00 | 102.28 : 0.00 | 122.72 : 0.00 | 109.64
resque/server : 1.21 | 103.49 : 1.73 | 124.45 : 1.68 | 111.32
resque_mailer : 0.00 | 103.49 : 0.00 | 124.45 : 0.00 | 111.32
rack-timeout : 0.00 | 103.49 : 0.00 | 124.45 : 0.00 | 111.32
chronic : 1.66 | 105.15 : 0.67 | 125.12 : 0.64 | 111.96
oink : 0.00 | 105.15 : 0.00 | 125.12 : 0.00 | 111.96
dotenv-rails : 0.00 | 105.15 : 0.00 | 125.12 : 0.00 | 111.96
jquery-rails : 0.00 | 105.15 : 0.03 | 125.15 : 0.00 | 111.96
jquery-ui-rails : 0.00 | 105.15 : 0.00 | 125.15 : 0.00 | 111.96
Run Code Online (Sandbox Code Playgroud)
我很清楚,我有一些非常基本的东西,我不知道如何将内存分配给Ruby进程,但我很难弄清楚为什么它看起来像是随机的.有人有什么想法?
我将进行大胆的猜测,并说这是由地址空间布局随机化以及与共享库的交互引起的,共享库的足迹受到不在测试用例中运行的程序的影响。
从 10.5 开始,OS X 获得了越来越多的 ASLR 支持,从 10.8 开始,甚至内核也被随机重新定位。
在某些情况下,ASLR 可能会导致程序段使用额外的页,具体取决于偏移量是否导致跨越页边界。由于有很多段和很多库,因此这种效果很难预测。
我还想知道(考虑到您所看到的巨大差异)这是否是 OS X 中的报告问题。我想知道共享对象的开销是否根据加载顺序不公平地收取。
您可以通过查阅 Stack Overflow 问题来测试这一点:在 Mac OS X Snow Leopard 中禁用 ASLR。