SORU
4 Aralık 2013, ÇARŞAMBA


Bir bellek sızıntısı bulma neden Ruby

Benim Raylar bir bellek sızıntısı kodu olduğunu keşfettim, buldumnekod sızdırıyor ama değilnedenbu kaçaklar. Raylar gerektirmeyecek bir deneme durumu aşağı azalttım:

require 'csspool'
require 'ruby-mass'

def report
    puts 'Memory '   `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)[1].to_s   'KB'
    Mass.print
end

report

# note I do not store the return value here
CSSPool::CSS::Document.parse(File.new('/home/jason/big.css'))

ObjectSpace.garbage_collect
sleep 1

report

ruby-mass sözde bellekteki tüm nesneleri görmemi sağlıyor. CSSPool CSS ayrıştırıcı racc dayanmaktadır. /home/jason/büyük.css a 1.5MB CSS file.

Bu çıkışları:

Memory 9264KB

==================================================
 Objects within [] namespace
==================================================
  String: 7261
  RubyVM::InstructionSequence: 1151
  Array: 562
  Class: 313
  Regexp: 181
  Proc: 111
  Encoding: 99
  Gem::StubSpecification: 66
  Gem::StubSpecification::StubLine: 60
  Gem::Version: 60
  Module: 31
  Hash: 29
  Gem::Requirement: 25
  RubyVM::Env: 11
  Gem::Specification: 8
  Float: 7
  Gem::Dependency: 7
  Range: 4
  Bignum: 3
  IO: 3
  Mutex: 3
  Time: 3
  Object: 2
  ARGF.class: 1
  Binding: 1
  Complex: 1
  Data: 1
  Gem::PathSupport: 1
  IOError: 1
  MatchData: 1
  Monitor: 1
  NoMemoryError: 1
  Process::Status: 1
  Random: 1
  RubyVM: 1
  SystemStackError: 1
  Thread: 1
  ThreadGroup: 1
  fatal: 1
==================================================

Memory 258860KB

==================================================
 Objects within [] namespace
==================================================
  String: 7456
  RubyVM::InstructionSequence: 1151
  Array: 564
  Class: 313
  Regexp: 181
  Proc: 113
  Encoding: 99
  Gem::StubSpecification: 66
  Gem::StubSpecification::StubLine: 60
  Gem::Version: 60
  Module: 31
  Hash: 30
  Gem::Requirement: 25
  RubyVM::Env: 13
  Gem::Specification: 8
  Float: 7
  Gem::Dependency: 7
  Range: 4
  Bignum: 3
  IO: 3
  Mutex: 3
  Time: 3
  Object: 2
  ARGF.class: 1
  Binding: 1
  Complex: 1
  Data: 1
  Gem::PathSupport: 1
  IOError: 1
  MatchData: 1
  Monitor: 1
  NoMemoryError: 1
  Process::Status: 1
  Random: 1
  RubyVM: 1
  SystemStackError: 1
  Thread: 1
  ThreadGroup: 1
  fatal: 1
==================================================

Bellek görebilirsinizyol. Bazı sayaçlar yukarı gitmek, ama hiçbir nesne CSSPool için özel hediye. Ruby kitle "" gibi referansları olan nesneleri kontrol yöntemi: . ındex kullandım

Mass.index.each do |k,v|
    v.each do |id|
        refs = Mass.references(Mass[id])
        puts refs if !refs.empty?
    end
end

Fakat yine de, bu bana bir şey CSSPool, gem bilgi sadece ilgili ve bu tür vermez.

Ayrıca "GC.çıkartmaya çalıştım"... . stat

puts GC.stat
CSSPool::CSS::Document.parse(File.new('/home/jason/big.css'))
ObjectSpace.garbage_collect
sleep 1
puts GC.stat

Sonuç:

{:count=>4, :heap_used=>126, :heap_length=>138, :heap_increment=>12, :heap_live_num=>50924, :heap_free_num=>24595, :heap_final_num=>0, :total_allocated_object=>86030, :total_freed_object=>35106}
{:count=>16, :heap_used=>6039, :heap_length=>12933, :heap_increment=>3841, :heap_live_num=>13369, :heap_free_num=>2443302, :heap_final_num=>0, :total_allocated_object=>3771675, :total_freed_object=>3758306}

Anladığım kadarıyla, bir nesne başvurulan ve çöp toplama olursa, o zaman o nesnenin bellekten temizlenmelidir. Ama burada olan şey görünmüyor.

Ayrıca C-düzey bellek sızıntısı hakkında çok şey okudum, ve CSSPool kullanır C kodu kullanan Racc beri, bu bir olasılık olduğunu düşünüyorum. Valgrind ile benim kod çalıştırmak var:

valgrind --partial-loads-ok=yes --undef-value-errors=no --leak-check=full --fullpath-after= ruby leak.rb 2> valgrind.txt

Sonuçlar here. Eğer bu C-düzey bir sızıntı teyit emin değilim, Ruby Valgrind anlamayan bellek ile bir şeyler yapıyor da okudum.

Sürüm:

  • Ruby 2.0.0-p247 (bu benim Raylar app çalışır)
  • Ruby-p392-ref 1.9.3 (ruby-kütle ile test için)
  • ruby kitle 0.1.3
  • CSSPool here 4.0.0
  • Otomotiv-6.4 ve Ubuntu 13.10

CEVAP
16 Aralık 2013, PAZARTESİ


Giriyorsunuz gibi görünüyorKayıp Dünyaburada. Sorun c-bağları racc da olduğunu sanmıyorum.

Ruby bellek yönetimi hem zarif hem de hantal. Nesneler (RVALUEs adlı) sözde saklaryığınlarıyaklaşık 16KB büyüklüğünde. , RVALUE düşük bir seviyede olur c-bir yapı, union farklı standart yakut nesne temsilleri içeren.

Böylece, kümeler *19 Ebat 40'tan fazla bayt olmayan nesneleri saklamak. *, , * ArrayHash20 vb gibi nesneler için. bu küçük nesneler yığını uyum anlamına gelir, ama bir eşik ulaşır ulaşmaz, Ruby kümeler dışında fazladan bir bellek ayrılmış olur.

Bu ekstra bellek esnektir; bir nesne GC çiğnenmiş oldu en kısa sürede serbest bırakılacaktır.big_string ile deneme durumu Yukarı-Aşağı davranış: bellek gösterir

def report
  puts 'Memory '   `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`
          .strip.split.map(&:to_i)[1].to_s   'KB'
end
report
big_var = " " * 10000000
report
big_var = nil 
report
ObjectSpace.garbage_collect
sleep 1
report
# ⇒ Memory 11788KB
# ⇒ Memory 65188KB
# ⇒ Memory 65188KB
# ⇒ Memory 11788KB

Ama kümeler (GC[:heap_length]) kendilerinideğildir yayımladıgeri OS için kazanılmış bir kez. Bak, senin test çalışmasına monoton bir değişiklik yapalım:

- big_var = " " * 10000000
  big_var = 1_000_000.times.map(&:to_s)

Ve işte, sihir:

# ⇒ Memory 11788KB
# ⇒ Memory 65188KB
# ⇒ Memory 65188KB
# ⇒ Memory 57448KB

Bellek dizisi ben her öge-çünkü artık OS, piyasaya geri döndütakım elbiseRVALUE boyutu vesaklanırruby öbek.

Eğer GC çalıştırıldı sonra GC.stat çıktısını inceleyin. eğer GC[:heap_used] değeri beklendiği gibi azalma olduğunu göreceksiniz. Ruby şimdi boş yığınları, bir sürü hazır.

Bu özetliyor:Sanmıyorum, c kod sızdırıyor. Sorun css senin büyük resmin base64 gösterimi içinde olduğunu düşünüyorum. İçinde ayrıştırıcı neler olduğunu hiçbir ipucu var, ama büyük dize ruby öbek sayısını artırmak için zorlar gibi görünüyor.

Umarım yardımcı olur.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • How to Cook ?

    How to Cook

    31 Ocak 2007
  • kruno j

    kruno j

    6 Mayıs 2007
  • ravinderosahn

    ravinderosah

    20 Temmuz 2009