Slide 1

Slide 1 text

Debugging and Profiling Rails App David Paluy January 2013

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Ruby is eating RAM

Slide 4

Slide 4 text

Agenda ● “Winter is coming!” ● Garbage Collector ● Debug Tools ● Profiling Tools

Slide 5

Slide 5 text

The Task: Send ~30,000 e-mails

Slide 6

Slide 6 text

Result Before

Slide 7

Slide 7 text

How Ruby Works? Physical RAM Process Heap Ruby Heap Ruby Heap Ruby Object Ruby Object Ruby Object Ruby Object Ruby Object Ruby Object

Slide 8

Slide 8 text

New Object allocation Free List A L L O C A T E D F R E E

Slide 9

Slide 9 text

New Object allocation Free List A L L O C A T E D

Slide 10

Slide 10 text

New Object allocation Free List is empty A L L O C A T E D

Slide 11

Slide 11 text

New Object allocation Free List is empty – Call GC A L L O C A T E D

Slide 12

Slide 12 text

GC Process ● GC finds non-reachable objects and adds them to Free List ● If Free List is still empty, another Heap allocated

Slide 13

Slide 13 text

MRI GC ● “Conservative”: any bit pattern could be a pointer (may produce false positive) ● “Stop the world”: no other Ruby code can execute during GC ● “Mark & Sweep”: mark all objects in use, than sweep away unmarked objects

Slide 14

Slide 14 text

More Objects => Longer GC => Slow

Slide 15

Slide 15 text

In our case – Out of Memory!

Slide 16

Slide 16 text

How to Debug? ● gem "pry-debugger" https://github.com/nixme/pry-debugger ● gem "debugger-pry" https://github.com/pry/debugger-pry

Slide 17

Slide 17 text

Tools ● ObjectSpace.count_objects ● GC debug - Enable heap dump support ● gdb.rb (only Linux) Note: memprof works only with Ruby 1.8

Slide 18

Slide 18 text

ObjectSpace.count_objects

Slide 19

Slide 19 text

Enable heap dump support to Ruby Install custom patched version of ruby Usage:

Slide 20

Slide 20 text

https://github.com/tmm1/gdb.rb Attached to existing process and examine the HEAP

Slide 21

Slide 21 text

Result After

Slide 22

Slide 22 text

Profiling Tools ● Ruby Benchmark ● ruby-prof ● perftools.rb (Google perftools for Ruby)

Slide 23

Slide 23 text

Benchmark ● gem 'benchmark_suite' https://github.com/evanphx/benchmark_suite

Slide 24

Slide 24 text

ruby-prof gem 'ruby-prof' https://github.com/rdp/ruby-prof

Slide 25

Slide 25 text

ruby-prof Measurements ● process time (RubyProf::PROCESS_TIME) ● wall time (RubyProf::WALL_TIME) ● cpu time (RubyProf::CPU_TIME) ● object allocations (RubyProf::ALLOCATIONS) ● memory usage (RubyProf::MEMORY) ● garbage collections runs (RubyProf::GC_RUNS) ● garbage collection time (RubyProf::GC_TIME)

Slide 26

Slide 26 text

perftools.rb https://github.com/tmm1/perftools.rb gem 'rack-perftools_profiler', :require => 'rack/perftools_profiler'

Slide 27

Slide 27 text

rack-perftools_profiler usage

Slide 28

Slide 28 text

KCacheGrind

Slide 29

Slide 29 text

Summary ● More Objects => Longer GC => Slow ● Examine your HEAP ● Use Tools

Slide 30

Slide 30 text

Q&A http://dpaluy.github.com @dpaluy [email protected] http://www.linkedin.com/in/davidpaluy