BitmapMarikingパッチのcopy-on-write評価(ruby1.9.0-4)

patch

 

benchmark

def cow_dump(pid, type=:none)
  rss = 0
  shared = 0
  private = 0
  open("/proc/#{pid}/smaps") do |f|
    is_heap = false
    while f.gets
      is_heap = true if /(\d+).+\[heap\]/ === $_
      if is_heap
        case $_
        when /Rss\:\s+(\d+)/
          rss += $1.to_i
        when /(Shared_Clean|Shared_Dirty)\:\s+(\d+)/
          shared += $2.to_i
        when /Private_Clean\:\s+(\d+)/
          private += $1.to_i
        when /Private_Dirty\:\s+(\d+)/
          private += $1.to_i
          is_heap = false
        end
      end
    end
  end
  puts <<EOS
== #{type}
Process id #{pid}
Rss\t#{rss}\tkb
Shared\t#{shared}\tkb
Private\t#{private}\tkb
EOS
end

@list = []
500000.times do
   @list << rand(36 ** 9).to_s(36)[1, 8]
end

def complement(word)
  res = []
  @list.each {|w| res << w if w.include? word}
  res
end

GC.start
fork do
  cow_dump($$, :child)
  complement("foo")
  GC.start
  cow_dump($$, :child)
  exit!
end
Process.waitall
cow_dump($$, :parent)

 

evalution

GC速度

  marx mark stop(msec) max sweep stop(msec) max total stop(msec) total diff(%)
v1.9.0-4 4.40 1.60 6.00 100%
v1.9.0-4_bsearch 211.21 7.20 218.41 3640%
v1.9.0-4_new 5.20 1.60 6.80 113%

 
子プロセスのメモリ使用状況

  rss (kB) share (kB) private (kB) private diff(%)
v1.9.0-4 20000 kB 244 kB 19756 kB 100%
v1.9.0-4_bsearch 20068 kB 17224 kB 2844 kB 14.40%
v1.9.0-4_new 20072 kB 16804 kB 3268 kB 16.54%

 

何が嬉しいのか

とりあえず、RubyEnterpriseEditionのグラフなど見てもらえばよいかと。
Welcome — Ruby Enterprise Edition
Apache+Passenger(mod_rails)の環境でメモリを消費していないという事を表している。
Apacheはforkを使うWebサーバなのでもちろんCoWの恩恵を受けるのだが、
今のRubyGCとCoWというのはすこぶる相性が悪い。
Apacheを使うとメモリ食いすぎー。ぶーぶー」などと感じたことがあるのではないだろうか?
(私は無い)
このパッチによってそれは改善される。
はずなので、試したら教えてください。お願いしますm(_ _)m
 
あとは、まつもとさんの解説を読んでもらうと、よく分かる。
 

technical information

あとで論文書くので、少々お待ちを。
ま、大したことないのだけど。。。