为什么每次启动时空的rails进程都会有不同的内存占用?

时间:2013-09-16 16:02:18

标签: ruby-on-rails ruby ruby-on-rails-3 memory-management

我们一直试图找出如何通过识别内存饥渴的宝石并寻找替代方案或解决方案来减少我们的rails应用程序的启动内存占用。

但我觉得OS X上有一个令人困惑的行为。

使用全新生成的rails应用程序(rails new memoryusage),没有Gemfile,没有模型,没有数据和没有事务,在启动rails c时,内存OSX显示相应的ruby进程vill会有所不同每次启动时,从低至60MB到高达65MB,没有可辨别的模式,为什么同一个应用程序可能需要每次执行更少或更多的内存。

我认为这必须以某种方式处理Ruby如何分配内存,但我并不完全清楚为什么它的内存分配会因为相同的代码和变量处理而变化太大。

当我们尝试在Gemfile中的每个gem之后计算进程消耗的内存时,我们有类似的不可预测的行为。我们加载一个vanilla rails进程,然后在rails c我们运行一个脚本来解析Gemfile并单独要求每个Gem,记录需求前后的内存,我们注意到的不仅是内存足迹没有一致的起点,但我们的记忆消耗中的增量“步骤”也有很大差异。

我们一个接一个地启动我们的进程三次,并测量每个gem所需的启动内存和增量内存。启动书的内存占用不仅在60MB和 92MB 之间反弹,而且我们在加载每个宝石时看到内存跳跃的点是不一致的 - 有时加载SASS会吃掉增加5MB,有时不会,有时active_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

我很清楚,我有一些非常基本的东西,我不知道如何将内存分配给Ruby进程,但是我很难弄清楚为什么它看起来似乎是随机的。有人有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我将采取疯狂的猜测并说这是由address space layout randomization和与共享库的交互引起的,这些共享库的脚印受到运行程序不在测试用例中的影响。

OS X从10.5开始越来越多地支持ASLR,从10.8开始,即使内核被随机重新定位。

在某些情况下,ASLR可能会导致程序段使用额外的页面,具体取决于偏移量是否会导致页面边界交叉。由于有许多细分和许多库,这种效果很难预测。

我也想知道(鉴于你看到的巨大差异)或许这是OS X中的一个报告问题。我想知道共享对象的开销是否会因负载顺序而受到不公平的收费。

您可以通过查看此Stack Overflow问题来测试此问题:Disabling ASLR in Mac OS X Snow Leopard.