рд░реВрдмреА рдореЗрдВ рдЫрд┐рдкреА рд╣реБрдИ рдореЗрдореЛрд░реА рд▓реАрдХ рдХреЛ рдбреАрдмрдЧ рдХрд░рдирд╛


2015 рдореЗрдВ, рдореИрдВрдиреЗ рдЙрди рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдерд╛ рдЬреЛ рд░реВрдмреА рдкреНрд░рдмрдВрдзрд┐рдд рдореЗрдореЛрд░реА рд▓реАрдХ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЬреНрдпрд╛рджрд╛рддрд░ рд▓реЗрдЦ рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдкреНрд░рдмрдВрдзрдиреАрдп рд▓реАрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреА рдЧрдИ рдереАред рдЗрд╕ рдмрд╛рд░ рдореИрдВ рдЙрди рдЯреВрд▓реНрд╕ рдФрд░ рдЯреНрд░рд┐рдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ рдЬрд┐рдирдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдк рд▓реАрдХ рдХреЛ рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд░реВрдмреА рдореЗрдВ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдирд╛ рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдореИрдВ mwrap, heaptrack, iseq_collector рдФрд░ chap рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ред


рдорд╛рдирд╡рд░рд╣рд┐рдд рд╕реНрдореГрддрд┐ рд▓реАрдХ


рдпрд╣ рдЫреЛрдЯрд╛ рд╕рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЙрд▓реЙрдХ рдХреЛ рд╕реАрдзреЗ рдХреЙрд▓ рдХреЗ рд╕рд╛рде рдПрдХ рд▓реАрдХ рдХреЛ рдЙрдХрд╕рд╛рддрд╛ рд╣реИред рдпрд╣ рдЖрд░рдПрд╕рдПрд╕ рдХреЗ 16 рдПрдордмреА рдХреА рдЦрдкрдд рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ 118 рдПрдордмреА рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред рдХреЛрдб 1024 рдмрд╛рдЗрдЯреНрд╕ рдХреЗ 100 рд╣рдЬрд╝рд╛рд░ рдмреНрд▓реЙрдХ рдореЗрдореЛрд░реА рдореЗрдВ рд░рдЦрддрд╛ рд╣реИ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ 50 рд╣рдЬрд╝рд╛рд░ рдХреЛ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИред

require 'fiddle' require 'objspace' def usage rss = `ps -p #{Process.pid} -o rss -h`.strip.to_i * 1024 puts "RSS: #{rss / 1024} ObjectSpace size #{ObjectSpace.memsize_of_all / 1024}" end def leak_memory pointers = [] 100_000.times do i = Fiddle.malloc(1024) pointers << i end 50_000.times do Fiddle.free(pointers.pop) end end usage # RSS: 16044 ObjectSpace size 2817 leak_memory usage # RSS: 118296 ObjectSpace size 3374 

рд╣рд╛рд▓рд╛рдБрдХрд┐ рдЖрд░рдПрд╕рдПрд╕ резрез, рдПрдордмреА рдХрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реА рд░реВрдмреА рд╡рд╕реНрддреБ рдХреЗрд╡рд▓ рддреАрди рдореЗрдЧрд╛рдмрд╛рдЗрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рд╣реИред рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдореЗрдВ, рд╣рдо рдЗрд╕ рдмрд╣реБрдд рдмрдбрд╝реА рд╕реНрдореГрддрд┐ рд░рд┐рд╕рд╛рд╡ рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣рд┐рд╕реНрд╕рд╛ рджреЗрдЦрддреЗ рд╣реИрдВред

рдЗрд╕ рддрд░рд╣ рдХреЗ рд░рд┐рд╕рд╛рд╡ рдХрд╛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдУрд▓реЗрдЧ рджрд╛рд╕рд╢реЗрд╡рд╕реНрдХреА рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рд╣реИ , рдореИрдВ рдЗрд╕ рдЕрджреНрднреБрдд рд▓реЗрдЦ рдХреЛ рдкрдврд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред

Mwrap рд▓рд╛рдЧреВ рдХрд░реЗрдВ


рд░реВрдмреА рдХреЗ рд▓рд┐рдП рдореЗрд╡рд╛рдк рдПрдХ рдореЗрдореЛрд░реА рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рд╣реИ рдЬреЛ рдореЙрд▓реЙрдХ рдФрд░ рдЗрд╕ рдкрд░рд┐рд╡рд╛рд░ рдХреЗ рдЕрдиреНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд░реЛрдХрдХрд░ рд╕реНрдореГрддрд┐ рдореЗрдВ рд╕рднреА рдбреЗрдЯрд╛ рдЖрд╡рдВрдЯрди рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рддрд╛ рд╣реИред рдпрд╣ LD_PRELOAD рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрд╕ рд╕реНрдерд╛рди рдФрд░ рдирд┐рдГрд╢реБрд▓реНрдХ рдореЗрдореЛрд░реА рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЧрд┐рдирддреА рдХреЗ рд▓рд┐рдП liburcu рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╕реА рдФрд░ рд░реВрдмреА рдХреЛрдб рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдмрд┐рдВрджреБ рдХреЗ рд▓рд┐рдП рдЖрд╡рдВрдЯрди рдФрд░ рд╡рд┐рд▓реЛрдкрди рдХрд╛рдЙрдВрдЯрд░ рдХреЛ рдЯреНрд░реИрдХ рдХрд░ рд╕рдХрддрд╛ рд╣реИред Mwrap рдЖрдХрд╛рд░ рдореЗрдВ рдЫреЛрдЯрд╛ рд╣реИ, рд▓рдЧрднрдЧ рдПрдХ рд░рд╛рд╖реНрдЯреНрд░реАрдпрдХреГрдд рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд▓рд┐рдП RSS рдЬрд┐рддрдирд╛ рдмрдбрд╝рд╛ рд╣реИ, рдФрд░ рд▓рдЧрднрдЧ рджреЛрдЧреБрдирд╛ рд╣реИред

рдпрд╣ рдЕрдкрдиреЗ рдмрд╣реБрдд рдЫреЛрдЯреЗ рдЖрдХрд╛рд░ рдФрд░ рд░реВрдмреА рд╕рдорд░реНрдерди рдореЗрдВ рдХрдИ рдЕрдиреНрдп рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рд╕реЗ рднрд┐рдиреНрди рд╣реИред рдпрд╣ рд░реВрдмреА рдлрд╛рдЗрд▓реЛрдВ рдореЗрдВ рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡реЗрд▓рдЧреНрд░рд┐рдВрдб + рдорд╕рд┐рдл рд╕реА-рд▓реЗрд╡рд▓ рдмреИрдХрдЯреНрд░реИрдХ рдФрд░ рд╕рдорд╛рди рдкреНрд░реЛрдлрд╛рдЗрд▓рд░реЛрдВ рддрдХ рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИред рдпрд╣ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЛ рдмрд╣реБрдд рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИред

рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ Mwrap рд╢реЗрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдпрд╣ LD_PRELOAD рд╡рд╛рддрд╛рд╡рд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдЧрд╛ рдФрд░ рд░реВрдмреА рдмрд╛рдЗрдирд░реА рдХреЛ рдЪрд▓рд╛рдПрдЧрд╛ред

рдЖрдЗрдП рд╣рдорд╛рд░реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ Mwrap рдЬреЛрдбрд╝реЗрдВ:

 require 'mwrap' def report_leaks results = [] Mwrap.each do |location, total, allocations, frees, age_total, max_lifespan| results << [location, ((total / allocations.to_f) * (allocations - frees)), allocations, frees] end results.sort! do |(_, growth_a), (_, growth_b)| growth_b <=> growth_a end results[0..20].each do |location, growth, allocations, frees| next if growth == 0 puts "#{location} growth: #{growth.to_i} allocs/frees (#{allocations}/#{frees})" end end GC.start Mwrap.clear leak_memory GC.start # Don't track allocations for this block Mwrap.quiet do report_leaks end 

рдЕрдм рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ Mwrap рдЖрд╡рд░рдг рдХреЗ рд╕рд╛рде рдЪрд▓рд╛рдПрдВ:

 % gem install mwrap % mwrap ruby leak.rb leak.rb:12 growth: 51200000 allocs/frees (100000/50000) leak.rb:51 growth: 4008 allocs/frees (1/0) 

Mwrap рдиреЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдПрдХ рд░рд┐рд╕рд╛рд╡ рдХрд╛ рд╕рд╣реА рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ (50,000 * 1024)ред рдФрд░ рди рдХреЗрд╡рд▓ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛, рдмрд▓реНрдХрд┐ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд▓рд╛рдЗрди ( i = Fiddle.malloc(1024) ) рдХреЛ рднреА рдЕрд▓рдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛, рдЬрд┐рд╕рд╕реЗ рд░рд┐рд╕рд╛рд╡ рд╣реБрдЖред рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рдиреЗ Fiddle.free рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдмрд╛рдзреНрдп рдХрд┐рдпрд╛ред

рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рд╣рдо рдПрдХ рдЖрдХрд▓рди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред Mwrap рдбрд╛рдпрд▓ рд╕рд╣рдХрд░реНрдореА рджреНрд╡рд╛рд░рд╛ рдЖрд╡рдВрдЯрд┐рдд рд╕рд╛рдЭрд╛ рдореЗрдореЛрд░реА рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдореЗрдореЛрд░реА рдХреЛ рдореБрдХреНрдд рдХрд░рдиреЗ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдХреЙрд▓ рдмрд┐рдВрджреБ рд╣реИ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдЖрдХрд╛рд░реЛрдВ рдХреЗ рдореЗрдореЛрд░реА рдмреНрд▓реЙрдХреЛрдВ рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИ, рддреЛ рдкрд░рд┐рдгрд╛рдо рдЧрд▓рдд рд╣реЛрдЧрд╛ред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдореВрд▓реНрдпрд╛рдВрдХрди рддрдХ рдкрд╣реБрдВрдЪ рд╣реИ: ((total / allocations) * (allocations - frees))

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд░рд┐рд╕рд╛рд╡ рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореНрд╡рд░реИрдк, рдЙрдореНрд░_рдЯреЛрдЯрд▓ рдХреЛ рдЯреНрд░реИрдХ age_total , рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдореБрдХреНрдд рд╡рд╕реНрддреБ рдХреЗ рдЬреАрд╡рди рдХрд╛рд▓ рдХрд╛ рдпреЛрдЧ рд╣реИ, рдФрд░ рдХреЙрд▓ рдмрд┐рдВрджреБ рдкрд░ рд╕рдмрд╕реЗ рдкреБрд░рд╛рдиреА рд╡рд╕реНрддреБ рдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЛ рднреА max_lifespan рдЯреНрд░реИрдХ max_lifespan ред рдпрджрд┐ age_total / frees рдмрдбрд╝реА рд╣реИ, рддреЛ рдХрдИ рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рдмрд╛рд╡рдЬреВрдж рдореЗрдореЛрд░реА рдЦрдкрдд рдмрдврд╝ рд░рд╣реА рд╣реИред

рд╢реЛрд░ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЗрд╡рдкреНрд░ рдореЗрдВ рдХрдИ рдорджрджрдЧрд╛рд░ рд╣реИрдВред Mwrap.clear рд╕рднреА рдЖрдВрддрд░рд┐рдХ рд╕рдВрдЧреНрд░рд╣рдг рдХреЛ рд╕рд╛рдлрд╝ рдХрд░ рджреЗрдЧрд╛ред Mwrap.quiet {} рдХреЛрдб рдХреЗ рдмреНрд▓реЙрдХ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Mwrap рдХреЛ рдордЬрдмреВрд░ рдХрд░реЗрдЧрд╛ред

Mwrap рдХреА рдПрдХ рдФрд░ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рд╢реЗрд╖рддрд╛ рдЖрд╡рдВрдЯрд┐рдд рдФрд░ рдореБрдХреНрдд рдХрд┐рдП рдЧрдП рдмрд╛рдЗрдЯреНрд╕ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдХреА рдЯреНрд░реИрдХрд┐рдВрдЧ рд╣реИред рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ clear рдирд┐рдХрд╛рд▓реЗрдВ рдФрд░ рдЙрд╕реЗ рдЪрд▓рд╛рдПрдВ:

 usage puts "Tracked size: #{(Mwrap.total_bytes_allocated - Mwrap.total_bytes_freed) / 1024}" # RSS: 130804 ObjectSpace size 3032 # Tracked size: 91691 

рдкрд░рд┐рдгрд╛рдо рдмрд╣реБрдд рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ 130 рдПрдордмреА рдХреЗ рдЖрд░рдПрд╕рдПрд╕ рдХреЗ рдЖрдХрд╛рд░ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдорд╛рд╡рд░рдк рдХреЗрд╡рд▓ 91 рдПрдордмреА рджреЗрдЦрддрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рд╣рдордиреЗ рдЕрдкрдиреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдмрдврд╝рд╛ рджрд┐рдпрд╛ рд╣реИред рдордкреНрд░ рдХреЗ рдмрд┐рдирд╛ рдирд┐рд╖реНрдкрд╛рджрди рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ 118 рдПрдордмреА рд▓рдЧрддреА рд╣реИ, рдФрд░ рдЗрд╕ рд╕рд╛рдзрд╛рд░рдг рдорд╛рдорд▓реЗ рдореЗрдВ рдЕрдВрддрд░ 12 рдПрдордмреА рдерд╛ред рдЖрд╡рдВрдЯрди / рдореБрдХреНрдд рдкреИрдЯрд░реНрди рд╡рд┐рдЦрдВрдбрди рдХрд╛ рдХрд╛рд░рдг рдмрдирд╛ред рдпрд╣ рдЬреНрдЮрд╛рди рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЕрдкреБрд╖реНрдЯ рдЧреНрд▓рд┐рдмреЗрд▓ рдорд▓реНрдХреЛрдХ рдЯреБрдХрдбрд╝реЗ рдХреЛ рдЗрддрдирд╛ рдЕрдзрд┐рдХ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрд░рдПрд╕рдПрд╕ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рд╕реНрдореГрддрд┐ рдХреА рдмрд╣реБрдд рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрд╡рддрдВрддреНрд░ рд╣реИред

рдХреНрдпрд╛ Mwrap рдПрдХ рдкреБрд░рд╛рдиреЗ рд░реЗрдбрдХрд╛рд░рдкреЗрдЯ рд░рд┐рд╕рд╛рд╡ рдХреЛ рдЕрд▓рдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИ?


рдЕрдкрдиреЗ рд▓реЗрдЦ рдореЗрдВ, рдУрд▓реЗрдЧ рд░реЗрдбрдХрд╛рд░рдкреЗрдЯ рдореЗрдВ рдПрдХ рдмрд╣реБрдд рдкрддрд▓реЗ рд░рд┐рд╕рд╛рд╡ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╣реБрдд рдЧрд╣рди рддрд░реАрдХреЗ рд╕реЗ рдЪрд░реНрдЪрд╛ рдХрд░рддрд╛ рд╣реИред рдХрдИ рд╡рд┐рд╡рд░рдг рд╣реИрдВред рдорд╛рдк рд▓реЗрдирд╛ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдпрджрд┐ рдЖрдк RSS рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╢реЗрдбреНрдпреВрд▓ рдирд╣реАрдВ рдмрдирд╛ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХрд┐рд╕реА рднреА рд▓реАрдХ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИред

рдЪрд▓реЛ рдПрдХ рдЯрд╛рдЗрдо рдорд╢реАрди рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ рдФрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рд▓реАрдХ рдХреЗ рд▓рд┐рдП Mwrap рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХрд┐рддрдирд╛ рдЖрд╕рд╛рди рд╣реИред

 def red_carpet_leak 100_000.times do markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, extensions = {}) markdown.render("hi") end end GC.start Mwrap.clear red_carpet_leak GC.start # Don't track allocations for this block Mwrap.quiet do report_leaks end 

рд░реЗрдбрдХрд╛рд░рдкреЗрдЯ 3.3.2:

 redcarpet.rb:51 growth: 22724224 allocs/frees (500048/400028) redcarpet.rb:62 growth: 4008 allocs/frees (1/0) redcarpet.rb:52 growth: 634 allocs/frees (600007/600000) 

рд░реЗрдбрдХрд╛рд░рдкреЗрдЯ 3.5.0:

 redcarpet.rb:51 growth: 4433 allocs/frees (600045/600022) redcarpet.rb:52 growth: 453 allocs/frees (600005/600000) 

рдпрджрд┐ рдЖрдк рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рд▓реЙрдЧ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдмрд╕ рдЗрд╕реЗ Mwrap рдореЗрдВ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рдХреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЖрдзреА рдЧрддрд┐ рд╕реЗ рдЪрд▓рд╛рдиреЗ рдХрд╛ рдЬреЛрдЦрд┐рдо рдЙрдард╛ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рд╕реНрдореГрддрд┐ рд▓реАрдХ рдХреА рдПрдХ рд╡рд┐рд╕реНрддреГрдд рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреА рдкрд╣рдЪрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд░рд╣рд╕реНрдпрдордп рд░рд┐рд╕рд╛рд╡


рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рд░реЗрд▓ рдХреЛ рд╕рдВрд╕реНрдХрд░рдг 6 рдореЗрдВ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЕрдиреБрднрд╡ рдмрд╣реБрдд рд╕рдХрд╛рд░рд╛рддреНрдордХ рдерд╛, рдкреНрд░рджрд░реНрд╢рди рд▓рдЧрднрдЧ рдПрдХ рд╣реА рд░рд╣рд╛ред рд░реЗрд▓реНрд╕ 6 рдореЗрдВ рдХреБрдЫ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВ рдЬрд┐рдирдХрд╛ рд╣рдо рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП Zeitwerk )ред рд░реЗрд▓реЛрдВ рдиреЗ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рддрд░реАрдХреЗ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛, рдЬрд┐рд╕рд╕реЗ рд╕рдВрдЧрддрддрд╛ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдмрджрд▓рд╛рд╡реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред рдЕрдкрдбреЗрдЯ рдХреЗ рдХреБрдЫ рджрд┐рдиреЛрдВ рдмрд╛рдж, рд╣рдордиреЗ рд╕рд╛рдЗрдбрдХреАрдХ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЗ рд▓рд┐рдП RSS рдореЗрдВ рд╡реГрджреНрдзрд┐ рджреЗрдЦреАред

рдЕрдкрдиреЗ рдЖрд╡рдВрдЯрди ( рд▓рд┐рдВрдХ ) рдХреЗ рдХрд╛рд░рдг рд╕реНрдореГрддрд┐ рдЙрдкрднреЛрдЧ рдореЗрдВ рддреЗрдЬ рд╡реГрджреНрдзрд┐ рдХреА рд╕реВрдЪрдирд╛ рджреА:

  source.encode! # Now, validate that the source we got back from the template # handler is valid in the default_internal. This is for handlers # that handle encoding but screw up unless source.valid_encoding? raise WrongEncodingError.new(source, Encoding.default_internal) end begin mod.module_eval(source, identifier, 0) rescue SyntaxError # Account for when code in the template is not syntactically valid; eg if we're using # ERB and the user writes <%= foo( %>, attempting to call a helper `foo` and interpolate # the result into the template, but missing an end parenthesis. raise SyntaxErrorInTemplate.new(self, original_source) end end def handle_render_error(view, e) if e.is_a?(Template::Error) 

рдкрд╣рд▓реЗ рддреЛ рд╣рдо рдмрд╣реБрдд рд╣реИрд░рд╛рди рдереЗред рд╣рдо рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рдереЗ рдХрд┐ рдореГрдЧ рд╕реЗ рдЕрд╕рдВрддреБрд╖реНрдЯ рдХреНрдпреЛрдВ? рд╢рд╛рдпрдж рд╡рд╣ рдЯреВрдЯ рдЧрдпрд╛? рд╕реНрдореГрддрд┐ рдХреА рдЦрдкрдд рдмрдврд╝рдиреЗ рдХреЗ рд╕рд╛рде, рд░реВрдмреА рдореЗрдВ рдвреЗрд░ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рд░рд╣реЗред



рд╣реАрдк рдореЗрдВ рджреЛ рдорд┐рд▓рд┐рдпрди рд╕реНрд▓реЙрдЯ рдХреЗрд╡рд▓ 78 рдПрдордмреА (40 рдмрд╛рдЗрдЯреНрд╕ рдкреНрд░рддрд┐ рд╕реНрд▓реЙрдЯ) рдХреА рдЦрдкрдд рд╣реБрдИред рд▓рд╛рдЗрдиреЗрдВ рдФрд░ рд╕рд░рдгрд┐рдпрд╛рдБ рдЕрдзрд┐рдХ рд╕реНрдерд╛рди рд▓реЗ рд╕рдХрддреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрднреА рднреА рдЕрд╕рд╛рдорд╛рдиреНрдп рд╕реНрдореГрддрд┐ рдЦрдкрдд рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╣рдордиреЗ рджреЗрдЦрд╛ рдерд╛ред рдЬрдм рдореИрдВрдиреЗ rbtrace -p SIDEKIQ_PID -e ObjectSpace.memsize_of_all рддреЛ рдЗрд╕рдХреА рдкреБрд╖реНрдЯрд┐ рдХреА рдЧрдИред

рд╕реНрдореГрддрд┐ рдХрд╣рд╛рдВ рдЧрдИ?

Heaptrack


рд╣реЗрдкрдЯреНрд░реИрдХ рд▓рд┐рдирдХреНрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдвреЗрд░ рдореЗрдореЛрд░реА рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рд╣реИред

рдорд┐рд▓рд┐рдпрди рд╡реЛрд▓реНрдл рдиреЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдордЭрд╛рдпрд╛ рдХрд┐ рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХрдИ рднрд╛рд╖рдгреЛрдВ ( 1 , 2 , 3 ) рдореЗрдВ рдмрд╛рдд рдХреА рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдПрдХ рдмрд╣реБрдд рд╣реА рдХреБрд╢рд▓ рджреЗрд╢реА рд╣реАрдк рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рд╣реИ, рдЬреЛ рд▓рд┐рдмреБрдирд╡рд┐рдВрдб рдХреА рдорджрдж рд╕реЗ , рдкреНрд░реЛрдлрд╛рдЗрд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рд╕реЗ рдмреИрдХрдЯреНрд░реИрдХреНрд╕ рдПрдХрддреНрд░ рдХрд░рддрд╛ рд╣реИред рдпрд╣ Valgrind / Massif рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрд╛рдлреА рддреЗрдЬрд╝ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдЕрд╕реНрдерд╛рдпреА рдкреНрд░реЛрдлрд╛рдЗрд▓рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред рдЗрд╕реЗ рдкрд╣рд▓реЗ рд╕реЗ рдЪрд▓ рд░рд╣реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ!

рдЕрдзрд┐рдХрд╛рдВрд╢ рдвреЗрд░ рдкреНрд░реЛрдлрд╛рдЗрд▓рд░реНрд╕ рдХреЗ рд╕рд╛рде, рдЬрдм рдореЙрд▓реЙрдХ рдкрд░рд┐рд╡рд╛рд░ рдореЗрдВ рд╣рд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣реЗрдкреНрдЯреНрд░реИрдХ рдХреЛ рдЧрд┐рдирдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдереЛрдбрд╝рд╛ рдзреАрдорд╛ рдХрд░ рджреЗрддреА рд╣реИред

рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдпрд╣рд╛рдВ рдХрд╛ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╕рдВрднрд╡ рд╣реИред рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП LD_PRELOAD рдпрд╛ GDB рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрд╡рд░реЛрдзрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рд╡рд┐рд╢реЗрд╖ FIFO рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП , рд╡рд╣ рдЬрд┐рддрдиреА рдЬрд▓реНрджреА рд╣реЛ рд╕рдХреЗ profiled рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рд╣реЗрдкрдЯреНрд░реИрдХ рд░реИрдкрд░ рдПрдХ рд╕рд░рд▓ рд╢реЗрд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред рджреВрд╕рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ FIFO рд╕реЗ рд╕реВрдЪрдирд╛ рдкрдврд╝рддреА рд╣реИ рдФрд░ рдСрди-рдж-рдлреНрд▓рд╛рдИ рд╕рдВрдкреАрдбрд╝рд┐рдд рдЯреНрд░реИрдХрд┐рдВрдЧ рдбреЗрдЯрд╛ред рдЪреВрдВрдХрд┐ рд╣реАрдкреНрдЯреНрд░реИрдХ "рдЪрдВрдХреНрд╕" рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЖрдк рдкреНрд░реЛрдлрд╛рдЗрд▓ рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рдХреБрдЫ рд╣реА рд╕реЗрдХрдВрдб рдмрд╛рдж рдкреНрд░реЛрдлрд╛рдЗрд▓ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рддреНрд░ рдХреЗ рдареАрдХ рдмреАрдЪ рдореЗрдВред рдмрд╕ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╕реНрдерд╛рди рдкрд░ рдХреЙрдкреА рдХрд░реЗрдВ рдФрд░ Heaptrack GUI рд▓реЙрдиреНрдЪ рдХрд░реЗрдВред

рдЗрд╕ GitLab рдЯрд┐рдХрдЯ рдиреЗ рдореБрдЭреЗ рд╣реАрдкреНрдЯреНрд░рд╛рдХ рд▓реЙрдиреНрдЪ рдХрд░рдиреЗ рдХреА рдмрд╣реБрдд рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдпрд╛ред рдЕрдЧрд░ рд╡реЗ рдЗрд╕реЗ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред

рд╣рдорд╛рд░рд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдПрдХ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдЪрд▓рддрд╛ рд╣реИ, рдФрд░ рдореБрдЭреЗ рдЗрд╕реЗ --cap-add=SYS_PTRACE рд╕рд╛рде рдкреБрдирдГ рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд╕реЗ GDB рдХреЛ ptrace рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдорд┐рд▓рддреА рд╣реИ, рдЬреЛ рдЦреБрдж рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Heaptrack рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдореБрдЭреЗ рдЧреИрд░- root рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкреНрд░реЛрдлрд╛рдЗрд▓ рдкрд░ root рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реЗрд▓ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯреА рд╕реА рд╣реИрдХ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рд╣рдордиреЗ рдПрдХ рд╕реАрдорд┐рдд рдЦрд╛рддреЗ рдХреЗ рддрд╣рдд рдХрдВрдЯреЗрдирд░ рдореЗрдВ рд╣рдорд╛рд░реЗ рдбрд┐рд╕реНрдХреЛрд░реНрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рд╣реИ)ред

рд╕рдм рдХреБрдЫ рд╣реЛ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рдХреЗрд╡рд▓ heaptrack -p PID рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдФрд░ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдкреНрд░рдХрдЯ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИред рд╣реАрдкреНрдЯреНрд░рд╛рдХ рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдЙрдкрдХрд░рдг рдирд┐рдХрд▓рд╛, рдореЗрдореЛрд░реА рд▓реАрдХ рдХреЗ рд╕рд╛рде рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╣рд░ рдЪреАрдЬ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рдерд╛ред



рдЧреНрд░рд╛рдл рдкрд░, рдЖрдкрдХреЛ рджреЛ cppjieba рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ, рдПрдХ cppjieba рдХрд╛рд░рдг, рджреВрд╕рд░рд╛ рд░реВрдмреА рдореЗрдВ objspace_xmalloc0 рдХрд╛рд░рдгред

рдореБрдЭреЗ cppjieba рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдерд╛ред рдЪреАрдиреА рднрд╛рд╖рд╛ рдХреЛ рдЦрдВрдбрд┐рдд рдХрд░рдирд╛ рдорд╣рдВрдЧрд╛ рд╣реИ, рдЖрдкрдХреЛ рдмрдбрд╝реЗ рд╢рдмреНрджрдХреЛрд╢реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд░рд┐рд╕рд╛рд╡ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рд░реВрдмреА рдореЗрдВ рд╕реНрдореГрддрд┐ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛, рдЬреЛ рдЕрднреА рднреА рдореБрдЭреЗ рдирд╣реАрдВ рдмрддрд╛рддрд╛ рд╣реИ?



рдореБрдЦреНрдп рд▓рд╛рдн iseq_set_sequence рдореЗрдВ compile.c рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд░рд┐рд╕рд╛рд╡ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЗ рдХрд╛рд░рдг рд╣реИред рдЗрд╕рдиреЗ рдорд╛рд╡рд░рдк рджреНрд╡рд╛рд░рд╛ рдЦреЛрдЬреЗ рдЧрдП рд░рд┐рд╕рд╛рд╡ рдХреЛ рд╕рд╛рдл рдХрд┐рдпрд╛ред рдЗрд╕рдХрд╛ рдХрд╛рд░рдг mod.module_eval(source, identifier, 0) , рдЬрд┐рд╕рдиреЗ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдмрдирд╛рдП рдЬреЛ рд╕реНрдореГрддрд┐ рд╕реЗ рд╣рдЯрд╛рдП рдирд╣реАрдВ рдЧрдП рдереЗред

рдЕрдЧрд░, рдкреВрд░реНрд╡рд╡реНрдпрд╛рдкреА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдореЗрдВ, рдореИрдВрдиреЗ рдзреНрдпрд╛рди рд╕реЗ рд░реВрдмреА рд╕реЗ рдПрдХ рдвреЗрд░ рдбрдВрдк рдорд╛рдирд╛, рддреЛ рдореИрдВрдиреЗ рдЗрди рд╕рднреА IMEMO рдкрд░ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЗрд╕ рдбрдВрдк рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдЗрди-рдкреНрд░реЛрд╕реЗрд╕ рдбрд╛рдпрдЧреНрдиреЛрд╕реНрдЯрд┐рдХреНрд╕ рдХреЗ рджреМрд░рд╛рди рд╡реЗ рдмрд╕ рдЕрджреГрд╢реНрдп рд╣реЛрддреЗ рд╣реИрдВред

рдЗрд╕ рдмрд┐рдВрджреБ рд╕реЗ, рдбрд┐рдмрдЧрд┐рдВрдЧ рдмрд╣реБрдд рд╕рд░рд▓ рдерд╛ред рдореИрдВрдиреЗ eval рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╕рднреА рдХреЙрд▓ рдЯреНрд░реИрдХ рдХрд┐рдП рдФрд░ рдЗрд╕рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд┐рдпрд╛ред рдореИрдВрдиреЗ рдкрд╛рдпрд╛ рдХрд┐ рд╣рдо рдмрд╛рд░-рдмрд╛рд░ рдПрдХ рдмрдбрд╝реЗ рд╡рд░реНрдЧ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝ рд░рд╣реЗ рд╣реИрдВред рдпрд╣рд╛рдБ рд╣рдордиреЗ рдЬрд┐рд╕ рдмрдЧ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд┐рдпрд╛ рдЙрд╕рдХрд╛ рдПрдХ рд╕рд░рд▓реАрдХреГрдд рджреГрд╢реНрдп рд╣реИ:

 require 'securerandom' module BigModule; end def leak_methods 10_000.times do method = "def _#{SecureRandom.hex}; #{"sleep;" * 100}; end" BigModule.module_eval(method) end end usage # RSS: 16164 ObjectSpace size 2869 leak_methods usage # RSS: 123096 ObjectSpace size 5583 

рд░реВрдмреА рдХреЗ рдкрд╛рд╕ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ RubyVM::InstructionSequence рджреГрд╢реНрдпреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд░реНрдЧ рд╣реИ: RubyVM::InstructionSequence ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд░реВрдмреА рдЗрди рдЖрд╡рд░рдг рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЖрд▓рд╕реА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдиреНрд╣реЗрдВ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд░реВрдк рд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рдЕрдХреНрд╖рдо рд╣реИред Koichi Sasada рдиреЗ iseq_collector рдирд┐рд░реНрднрд░рддрд╛ рдмрдирд╛рдИред рдпрджрд┐ рд╣рдо рдЗрд╕ рдХреЛрдб рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЕрдкрдиреА рдЫреБрдкреА рд╣реБрдИ рдореЗрдореЛрд░реА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ:

 require 'iseq_collector' puts "#{ObjectSpace.memsize_of_all_iseq / 1024}" # 98747 ObjectSpace.memsize_of_all_iseq 

рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд░рдо рдХреЛ рдЙрддреНрдкреНрд░реЗрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рдореЗрдореЛрд░реА рдЦрдкрдд рдХреЛ рдереЛрдбрд╝рд╛ рдмрдврд╝рд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдХрдЪрд░рд╛ рдХрд▓реЗрдХреНрдЯрд░ рдХреЛ рдереЛрдбрд╝рд╛ рдФрд░ рдХрд╛рдо рджреЗ рд╕рдХрддрд╛ рд╣реИред

рдпрджрд┐, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдХрд▓реЗрдХреНрдЯрд░ рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдФрд░ рдмрд╛рдж рдореЗрдВ ISEQs рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ ObjectSpace.memsize_of_all_iseq рд╣рдорд╛рд░реЗ рдХрд╛рдЙрдВрдЯрд░ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж RubyVM::InstructionSequence рд╢реНрд░реЗрдгреА рдХреЗрд╡рд▓ 0 рд╕реЗ 11128 рддрдХ рдмрдврд╝ RubyVM::InstructionSequence (рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ):

 def count_iseqs ObjectSpace.each_object(RubyVM::InstructionSequence).count end 

рдпреЗ рдЖрд╡рд░рдг рдкреВрд░реЗ рд╡рд┐рдзрд┐ рдХреЗ рджреМрд░рд╛рди рдмрдиреЗ рд░рд╣реЗрдВрдЧреЗ, рдЗрдиреНрд╣реЗрдВ рдХреВрдбрд╝рд╛ рдЙрдард╛рдиреЗ рд╡рд╛рд▓реЗ рдХреЗ рдкреВрд░реЗ рджреМрд░реЗ рдХреЗ рд╕рд╛рде рдЬрд╛рдирд╛ рд╣реЛрдЧрд╛ред рдИрдореЗрд▓ рдЯреЗрдореНрдкреНрд▓реЗрдЯ ( рд╣реЙрдЯрдлрд┐рдХреНрд╕ 1 , рд╣реЙрдЯрдлрд┐рдХреНрд╕ 2 ) рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╡рд░реНрдЧ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рдорд╛рд░реА рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдХреА рдЧрдИ рдереАред

рддрдбрд╝рдХрдирд╛


рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди, рдореИрдВрдиреЗ рдПрдХ рдмрд╣реБрдд рд╣реА рджрд┐рд▓рдЪрд╕реНрдк рдЙрдкрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рдХреБрдЫ рд╕рд╛рд▓ рдкрд╣рд▓реЗ, рдЯрд┐рдо рдмреЛрдбреА рдиреЗ рдореЗрдореЛрд░реА рд▓реАрдХ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП VMWare рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдПрдХ рдЖрдВрддрд░рд┐рдХ рдЙрдкрдХрд░рдг рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рд╛ рдФрд░ рдЕрдкрдирд╛ рдХреЛрдб рдЦреБрд▓рд╛ рдмрдирд╛рдпрд╛ред рдпрд╣рд╛рдБ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХрдорд╛рддреНрд░ рд╡реАрдбрд┐рдпреЛ рд╣реИ рдЬрд┐рд╕реЗ рдореИрдВ рдЦреЛрдЬрдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣рд╛: https://www.youtube.com/watch?v=EZ2n3kGtVVk ред рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдорд╛рди рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЗрд╕ рдПрдХ рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд░ рдХреЛрдИ рдкреНрд░рднрд╛рд╡ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рд╣реИред рдпрд╣ рдмрд╕ рдореБрдЦреНрдп рдбрдВрдк рдХреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдЧреНрд▓рд┐рдмрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдЖрд╡рдВрдЯрдирдХрд░реНрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЬреЗрдорд▓реЙрдХ / рдЯреАрд╕реАрдПрдорд▓реЛрдХреЗ, рдЖрджрд┐ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╕рдорд░реНрдерди рдирд╣реАрдВ рд╣реИ)ред

рдЪреИрдк рдХреЗ рд╕рд╛рде, рдореЗрд░реЗ рдкрд╛рд╕ рдЬреЛ рд▓реАрдХ рд╣реИ, рдЙрд╕рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред рдХреБрдЫ рд╡рд┐рддрд░рдгреЛрдВ рдореЗрдВ рдПрдХ рдЪреИрдк рдмрд╛рдЗрдирд░реА рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рдЗрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕реНрд░реЛрдд рдХреЛрдб рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд╣ рдмрд╣реБрдд рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рд╕рдорд░реНрдерд┐рдд рд╣реИред

 # 444098 is the `Process.pid` of the leaking process I had sudo gcore -p 444098 chap core.444098 chap> summarize leaked Unsigned allocations have 49974 instances taking 0x312f1b0(51,573,168) bytes. Unsigned allocations of size 0x408 have 49974 instances taking 0x312f1b0(51,573,168) bytes. 49974 allocations use 0x312f1b0 (51,573,168) bytes. chap> list leaked ... Used allocation at 562ca267cdb0 of size 408 Used allocation at 562ca267d1c0 of size 408 Used allocation at 562ca267d5d0 of size 408 ... chap> summarize anchored .... Signature 7fbe5caa0500 has 1 instances taking 0xc8(200) bytes. 23916 allocations use 0x2ad7500 (44,922,112) bytes. 

рдЪреИрдк рдЕрд▓рдЧ-рдЕрд▓рдЧ рдореЗрдореЛрд░реА рдХреЗ рд╕реНрдерд╛рдиреЛрдВ рдХреА рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рд╣рд╕реНрддрд╛рдХреНрд╖рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдпрд╣ GDB рдХреЛ рдкреВрд░рдХ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд░реВрдмреА рдореЗрдВ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХрд░рддреЗ рд╕рдордп, рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдмрд╣реБрдд рдорджрдж рдорд┐рд▓ рд╕рдХрддреА рд╣реИ рдХрд┐ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд┐рд╕ рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реА рд╣реИред рдпрд╣ рдХреБрд▓ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХреА рдЧрдИ рдореЗрдореЛрд░реА рдХреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реИ, рдХрднреА-рдХрднреА рдЧреНрд▓рд┐рдмреЗрдХ рдорд╛рд▓реЙрдХ рдЗрддрдирд╛ рдЯреБрдХрдбрд╝рд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХреА рдЧрдИ рдорд╛рддреНрд░рд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЖрд░рдПрд╕рдПрд╕ рд╕реЗ рдмрд╣реБрдд рдЕрд▓рдЧ рд╣реЛ рд╕рдХрддреА рд╣реИред рдЖрдк рдЪрд░реНрдЪрд╛ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ: рдлрд╝реАрдЪрд░ # 14759: [PATCH] gl_c malloc рдХреЗ рд▓рд┐рдП M_ARENA_MAX рд╕реЗрдЯ рдХрд░реЗрдВ - рд░реВрдмреА рдорд╛рд╕реНрдЯрд░ - рд░реВрдмреА рдЕрдВрдХ рдЯреНрд░реИрдХрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо ред рдЪреИрдк рд╕рднреА рдЙрдкрдпреЛрдЧ рдХреА рдЧрдИ рдореЗрдореЛрд░реА рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЧрд┐рдирдиреЗ рдФрд░ рдЙрд╕рдХреЗ рдЖрд╡рдВрдЯрди рдХрд╛ рдЧрд╣рд░рд╛рдИ рд╕реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЪреИрдк рдХреЛ рд▓реАрдХ рдФрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдРрд╕реА рдЕрд╕реЗрдВрдмрд▓реА рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдХрдлрд╝реНрд▓реЛрдЬрд╝ рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдХрд╛рдо рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВ


рдЗрд╕ рдбрд┐рдмрдЧрд┐рдВрдЧ рд░рд╛рдЙрдВрдб рдиреЗ рдореБрдЭреЗ рд╣рдорд╛рд░реЗ рд╕рд╣рд╛рдпрдХ рдЯреВрд▓рдХрд┐рдЯ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХреБрдЫ рдкреНрд░рд╢реНрди рдЙрдард╛рдП:


рд╕рд╛рд░рд╛рдВрд╢


рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдореЗрдореЛрд░реА рд▓реАрдХ рдХреЛ рдбрд┐рдмрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░рд╛ рдЖрдЬ рдХрд╛ рдЯреВрд▓рдХрд┐рдЯ 4 рд╕рд╛рд▓ рдкрд╣рд▓реЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд╣реИ! рд╡рд┐рдХрд╛рд╕ рдФрд░ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рджреМрд░рд╛рди рдЙрддреНрдкрдиреНрди рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╕реНрдореГрддрд┐ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Mwrap, Heaptrack рдФрд░ chap рдмрд╣реБрдд рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╣реИрдВред

рдпрджрд┐ рдЖрдк рд░реВрдмреА рдореЗрдВ рдПрдХ рд╕рд░рд▓ рд╕реНрдореГрддрд┐ рд░рд┐рд╕рд╛рд╡ рдХреЗ рд▓рд┐рдП рд╢рд┐рдХрд╛рд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдЕрдкрдиреЗ 2015 рдХреЗ рд▓реЗрдЦ рдХреЛ рдкрдврд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ , рдЕрдзрд┐рдХрд╛рдВрд╢ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рдпрд╣ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИред

рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЕрдЧрд▓реА рдмрд╛рд░ рдЬрдм рдЖрдк рдХрд┐рд╕реА рдЬрдЯрд┐рд▓ рджреЗрд╢реА рд╕реНрдореГрддрд┐ рд░рд┐рд╕рд╛рд╡ рдХреЛ рдбреАрдмрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ рддреЛ рдЖрдкрдХреЛ рдпрд╣ рдЖрд╕рд╛рди рд▓рдЧреЗрдЧрд╛ред

Source: https://habr.com/ru/post/hi473408/


All Articles