SlideShare una empresa de Scribd logo
1 de 131
Descargar para leer sin conexión
Debugging Ruby
 with MongoDB
    Aman Gupta
     @tmm1
debugging ruby?

• i use ruby
debugging ruby?

• i use ruby
• my ruby processes
  use a lot of ram
debugging ruby?

• i use ruby
• my ruby processes
  use a lot of ram
• i want to fix this
let’s build a debugger
• step 1: collect data
 • list of all ruby
    objects in memory
let’s build a debugger
• step 1: collect data
 • list of all ruby
    objects in memory


• step 2: analyze data
 • group by type
 • group by file/line
version 1: collect data
 • simple patch to ruby VM (300 lines of C)
  • http://gist.github.com/73674
 • simple text based output format
0x154750   @   -e:1   is   OBJECT of type: T
0x15476c   @   -e:1   is   HASH which has data
0x154788   @   -e:1   is   ARRAY of len: 0
0x1547c0   @   -e:1   is   STRING (SHARED) len: 2 and val: hi
0x1547dc   @   -e:1   is   STRING len: 1 and val: T
0x154814   @   -e:1   is   CLASS named: T inherits from Object
0x154a98   @   -e:1   is   STRING len: 2 and val: hi
0x154b40   @   -e:1   is   OBJECT of type: Range
version 1: analyze data
$ wc -l /tmp/ruby.heap

 1571529 /tmp/ruby.heap
version 1: analyze data
$ wc -l /tmp/ruby.heap

 1571529 /tmp/ruby.heap

$ cat /tmp/ruby.heap | awk '{ print $3 }' | sort |
uniq -c | sort -g | tail -1

 236840 memcached/memcached.rb:316
version 1: analyze data
$ wc -l /tmp/ruby.heap

 1571529 /tmp/ruby.heap

$ cat /tmp/ruby.heap | awk '{ print $3 }' | sort |
uniq -c | sort -g | tail -1

 236840 memcached/memcached.rb:316

$ grep "memcached.rb:316" /tmp/ruby.heap | awk
'{ print $5 }' | sort | uniq -c | sort -g | tail -5

     10948   ARRAY
     20355   OBJECT
     30744   DATA
     64952   HASH
    123290   STRING
version 1
version 1
• it works!
version 1
• it works!
• but...
version 1
• it works!
• but...
 • must patch and rebuild ruby binary
version 1
• it works!
• but...
 • must patch and rebuild ruby binary
 • no information about references between
    objects
version 1
• it works!
• but...
 • must patch and rebuild ruby binary
 • no information about references between
    objects
 • limited analysis via shell scripting
version 2 goals
version 2 goals
• better data format
version 2 goals
• better data format
 • simple: one line of text per object
version 2 goals
• better data format
 • simple: one line of text per object
 • expressive: include all details about
    object contents and references
version 2 goals
• better data format
 • simple: one line of text per object
 • expressive: include all details about
    object contents and references
 • easy to use: easy to generate from C
    code & easy to consume from various
    scripting languages
JSON!
version 2 is memprof
version 2 is memprof
• no patches to ruby necessary
 • gem install memprof
 • require ‘memprof’
 • Memprof.dump_all(“/tmp/app.json”)
version 2 is memprof
• no patches to ruby necessary
 • gem install memprof
 • require ‘memprof’
 • Memprof.dump_all(“/tmp/app.json”)
• C extension for MRI ruby VM
  http://github.com/ice799/memprof
 • uses libyajl to dump out all ruby objects
    as json
Memprof.dump{
strings   }
            “hello” + “world”
Memprof.dump{
        strings                 }
                                  “hello” + “world”




{
    "_id": "0x19c610",        memory address of object
    "file": "-e",
    "line": 1,

    "type": "string",
    "class": "0x1ba7f0",
    "class_name": "String",

    "length": 10,
    "data": "helloworld"
}
Memprof.dump{
        strings                  }
                                   “hello” + “world”




{
    "_id": "0x19c610",        memory address of object
    "file": "-e",             file and line where string
    "line": 1,
                              was created
    "type": "string",
    "class": "0x1ba7f0",
    "class_name": "String",

    "length": 10,
    "data": "helloworld"
}
Memprof.dump{
        strings                  }
                                   “hello” + “world”




{
    "_id": "0x19c610",        memory address of object
    "file": "-e",             file and line where string
    "line": 1,
                              was created
    "type": "string",
    "class": "0x1ba7f0",      address of the class object
    "class_name": "String",   “String”

    "length": 10,
    "data": "helloworld"
}
Memprof.dump{
        strings                  }
                                   “hello” + “world”




{
    "_id": "0x19c610",        memory address of object
    "file": "-e",             file and line where string
    "line": 1,
                              was created
    "type": "string",
    "class": "0x1ba7f0",      address of the class object
    "class_name": "String",   “String”

    "length": 10,             length and contents
    "data": "helloworld"      of this string instance
}
arrays
         Memprof.dump{
           [
             1,
             :b,
             2.2,
             “d”
           ]
         }
arrays
                             Memprof.dump{
                               [
                                 1,
                                 :b,
{
    "_id": "0x19c5c0",
                                 2.2,
                                 “d”
    "class": "0x1b0d18",       ]
    "class_name": "Array",   }

    "length": 4,
    "data": [
      1,
      ":b",

        "0x19c750",
        "0x19c598"
    ]
}
arrays
                                        Memprof.dump{
                                          [
                                            1,
                                            :b,
{
    "_id": "0x19c5c0",
                                            2.2,
                                            “d”
    "class": "0x1b0d18",                  ]
    "class_name": "Array",              }

    "length": 4,
    "data": [
      1,                     integers and symbols are
      ":b",                  stored in the array itself
        "0x19c750",
        "0x19c598"
    ]
}
arrays
                                        Memprof.dump{
                                          [
                                            1,
                                            :b,
{
    "_id": "0x19c5c0",
                                            2.2,
                                            “d”
    "class": "0x1b0d18",                  ]
    "class_name": "Array",              }

    "length": 4,
    "data": [
      1,                     integers and symbols are
      ":b",                  stored in the array itself
        "0x19c750",          floats and strings are
        "0x19c598"           separate ruby objects
    ]
}
hashes
         Memprof.dump{
           {
             :a => 1,
             “b” => 2.2
           }
         }
hashes
                               Memprof.dump{
                                 {
                                   :a => 1,
                                   “b” => 2.2
{                                }
    "_id": "0x19c598",         }
    "type": "hash",
    "class": "0x1af170",
    "class_name": "Hash",

    "default": null,

    "length": 2,
    "data": [
      [ ":a", 1 ],
      [ "0xc728", "0xc750" ]
    ]
}
hashes
                                        Memprof.dump{
                                          {
                                            :a => 1,
                                            “b” => 2.2
{                                         }
    "_id": "0x19c598",                  }
    "type": "hash",
    "class": "0x1af170",
    "class_name": "Hash",

    "default": null,

    "length": 2,
    "data": [
      [ ":a", 1 ],
                               hash entries as key/value
      [ "0xc728", "0xc750" ]   pairs
    ]
}
hashes
                                        Memprof.dump{
                                          {
                                            :a => 1,
                                            “b” => 2.2
{                                         }
    "_id": "0x19c598",                  }
    "type": "hash",
    "class": "0x1af170",
    "class_name": "Hash",

    "default": null,           no default proc
    "length": 2,
    "data": [
      [ ":a", 1 ],
                               hash entries as key/value
      [ "0xc728", "0xc750" ]   pairs
    ]
}
classes
          Memprof.dump{
            class Hello
              @@var=1
              Const=2
              def world() end
            end
          }
classes
                               Memprof.dump{
                                 class Hello
                                   @@var=1
                                   Const=2
{                                  def world() end
    "_id": "0x19c408",
                                 end
    "type": "class",           }
    "name": "Hello",
    "super": "0x1bfa48",
    "super_name": "Object",

    "ivars": {
       "@@var":   1,
       "Const":   2
    },
    "methods":    {
       "world":   "0x19c318"
    }
}
classes
                                   Memprof.dump{
                                     class Hello
                                       @@var=1
                                       Const=2
{                                      def world() end
    "_id": "0x19c408",
                                     end
    "type": "class",               }
    "name": "Hello",
    "super": "0x1bfa48",       superclass object reference
    "super_name": "Object",

    "ivars": {
       "@@var":   1,
       "Const":   2
    },
    "methods":    {
       "world":   "0x19c318"
    }
}
classes
                                   Memprof.dump{
                                     class Hello
                                       @@var=1
                                       Const=2
{                                      def world() end
    "_id": "0x19c408",
                                     end
    "type": "class",               }
    "name": "Hello",
    "super": "0x1bfa48",       superclass object reference
    "super_name": "Object",

    "ivars": {                 class variables and constants
       "@@var":   1,           are stored in the instance
       "Const":   2
    },                         variable table
    "methods":    {
       "world":   "0x19c318"
    }
}
classes
                                   Memprof.dump{
                                     class Hello
                                       @@var=1
                                       Const=2
{                                      def world() end
    "_id": "0x19c408",
                                     end
    "type": "class",               }
    "name": "Hello",
    "super": "0x1bfa48",       superclass object reference
    "super_name": "Object",

    "ivars": {                 class variables and constants
       "@@var":   1,           are stored in the instance
       "Const":   2
    },                         variable table
    "methods":    {
       "world":   "0x19c318"   references to method objects
    }
}
version 2: analyze data
version 2: memprof.com
   a web-based heap visualizer and leak analyzer
built on...
built on...


    $ mongoimport
        -d memprof
        -c rails
        --file /tmp/app.json
    $ mongo memprof
built on...


    $ mongoimport
        -d memprof
        -c rails
        --file /tmp/app.json
    $ mongo memprof

                 let’s run some queries.
how many objects?
> db.rails.count()
809816

 • ruby scripts create a lot of objects
 • usually not a problem, but...
  • MRI has a naïve stop-the-world mark/
     sweep GC
  • fewer objects = faster GC = better
     performance
what types of objects?
> db.rails.distinct(‘type’)

[‘array’,
 ‘bignum’,
 ‘class’,
 ‘float’,
 ‘hash’,
 ‘module’,
 ‘node’,
 ‘object’,
 ‘regexp’,
 ‘string’,
 ...]
mongodb: distinct
mongodb: distinct
•   distinct(‘type’)
    list of types of objects
mongodb: distinct
•   distinct(‘type’)
    list of types of objects
•   distinct(‘file’)
    list of source files
mongodb: distinct
•   distinct(‘type’)
    list of types of objects
•   distinct(‘file’)
    list of source files
•   distinct(‘class_name’)
    list of instance class names
mongodb: distinct
•   distinct(‘type’)
    list of types of objects
•   distinct(‘file’)
    list of source files
•   distinct(‘class_name’)
    list of instance class names
• optionally filter first
    •   distinct(‘name’, {type:“class”})
        names of all defined classes
improve performance
             with indexes

> db.rails.ensureIndex({‘type’:1})
improve performance
             with indexes

> db.rails.ensureIndex({‘type’:1})

> db.rails.ensureIndex(
    {‘file’:1},
    {background:true}
)
mongodb: ensureIndex
• add an index on a field (if it doesn’t exist yet)
• improve performance of queries against
  common fields: type, class_name, super, file
mongodb: ensureIndex
• add an index on a field (if it doesn’t exist yet)
• improve performance of queries against
  common fields: type, class_name, super, file
• can index embedded field names
  •   ensureIndex(‘methods.add’)

  •   find({‘methods.add’:{$exists:true}})
      find classes that define the method add
how many objs per type?
> db.rails.group({
   initial: {count:0},
   key: {type:true},              group on type
   cond: {},
   reduce: function(obj, out) {
     out.count++
   }
}).sort(function(a,b){
   return a.count - b.count
})
how many objs per type?
> db.rails.group({
   initial: {count:0},
   key: {type:true},              group on type
   cond: {},
   reduce: function(obj, out) {
                                  increment count
     out.count++
                                  for each obj
   }
}).sort(function(a,b){
   return a.count - b.count
})
how many objs per type?
> db.rails.group({
   initial: {count:0},
   key: {type:true},              group on type
   cond: {},
   reduce: function(obj, out) {
                                  increment count
     out.count++
                                  for each obj
   }
}).sort(function(a,b){
   return a.count - b.count       sort results
})
how many objs per type?
 [
     ...,
     {type: ‘array’, count: 7621},
     {type: ‘string’, count: 69139},
     {type: ‘node’, count: 365285}
 ]
how many objs per type?
 [
     ...,
     {type: ‘array’, count: 7621},
     {type: ‘string’, count: 69139},
     {type: ‘node’, count: 365285}
 ]
                                lots of nodes
how many objs per type?
 [
     ...,
     {type: ‘array’, count: 7621},
     {type: ‘string’, count: 69139},
     {type: ‘node’, count: 365285}
 ]
                                        lots of nodes

 • nodes represent ruby code
  • stored like any other ruby object
  • makes ruby completely dynamic
mongodb: group
mongodb: group
• cond: query to filter objects before
  grouping
mongodb: group
• cond: query to filter objects before
  grouping
• key: field(s) to group on
mongodb: group
• cond: query to filter objects before
  grouping
• key: field(s) to group on
• initial: initial values for each group’s
  results
mongodb: group
• cond: query to filter objects before
  grouping
• key: field(s) to group on
• initial: initial values for each group’s
  results
• reduce: aggregation function
mongodb: group
mongodb: group
• bykey: {type:1}
     type or class
 •
 •   key: {class_name:1}
mongodb: group
• bykey: {type:1}
     type or class
 •
 •   key: {class_name:1}

• bykey:&{file:1, line:1}
     file line
 •
mongodb: group
• bykey: {type:1}
     type or class
 •
 •   key: {class_name:1}

• bykey:&{file:1, line:1}
     file line
 •
• bycond: in a specific file
     type
 •         {file: “app.rb”},
      key: {file:1, line:1}
mongodb: group
• bykey: {type:1}
     type or class
 •
 •   key: {class_name:1}

• bykey:&{file:1, line:1}
     file line
 •
• bycond: in a specific file
     type
 •         {file: “app.rb”},
      key: {file:1, line:1}

• bycond: {file:“app.rb”,type:‘string’},
     length of strings in a specific file
 •
      key: {length:1}
what subclasses String?
> db.rails.find(
  {super_name:"String"},
  {name:1}
)

{name:   "ActiveSupport::SafeBuffer"}
{name:   "ActiveSupport::StringInquirer"}
{name:   "SQLite3::Blob"}
{name:   "ActiveModel::Name"}
{name:   "Arel::Attribute::Expressions"}
{name:   "ActiveSupport::JSON::Variable"}
what subclasses String?
> db.rails.find(
  {super_name:"String"},
  {name:1}             select only name field
)

{name:   "ActiveSupport::SafeBuffer"}
{name:   "ActiveSupport::StringInquirer"}
{name:   "SQLite3::Blob"}
{name:   "ActiveModel::Name"}
{name:   "Arel::Attribute::Expressions"}
{name:   "ActiveSupport::JSON::Variable"}
mongodb: find
mongodb: find

•   find({type:‘string’})
    all strings
mongodb: find

•   find({type:‘string’})
    all strings
•   find({type:{$ne:‘string’}})
    everything except strings
mongodb: find

•   find({type:‘string’})
    all strings
•   find({type:{$ne:‘string’}})
    everything except strings
•   find({type:‘string’}, {data:1})
    only select string’s data field
the largest objects?
> db.rails.find(
  {type:
     {$in:['string','array','hash']}
  },
  {type:1,length:1}
).sort({length:-1}).limit(3)

{type: "string", length: 2308}
{type: "string", length: 1454}
{type: "string", length: 1238}
mongodb: sort, limit/skip
mongodb: sort, limit/skip
•   sort({length:-1,file:1})
    sort by length desc, file asc
mongodb: sort, limit/skip
•   sort({length:-1,file:1})
    sort by length desc, file asc
•   limit(10)
    first 10 results
mongodb: sort, limit/skip
•   sort({length:-1,file:1})
    sort by length desc, file asc
•   limit(10)
    first 10 results
•   skip(10).limit(10)
    second 10 results
when were objs created?
• useful to look at objects over time
 • each obj has a timestamp of when it was
    created
when were objs created?
• useful to look at objects over time
 • each obj has a timestamp of when it was
    created
 • find minimum time, call it
    start_time
when were objs created?
• useful to look at objects over time
 • each obj has a timestamp of when it was
    created
 • find minimum time, call it
    start_time
 • create buckets for every
    minute of execution since
    start
when were objs created?
• useful to look at objects over time
 • each obj has a timestamp of when it was
    created
 • find minimum time, call it
    start_time
 • create buckets for every
    minute of execution since
    start
 • place objects into buckets
when were objs created?
> db.rails.mapReduce(function(){
    var secs = this.time - start_time;
    var mins_since_start = secs % 60;
    emit(mins_since_start, 1);
  }, function(key, vals){
    for(var i=0,sum=0; i<vals.length;
        sum += vals[i++]);
    return sum;
  }, {
    scope: { start_time: db.rails.find
().sort({time:1}).limit(1)[0].time }
  }               start_time = min(time)
)
{result:"tmp.mr_1272615772_3"}
mongodb: mapReduce
• arguments
 • map: function that emits one or more
    key/value pairs given each object this
 • reduce: function to return aggregate
    result, given key and list of values
 • scope: global variables to set for funcs
mongodb: mapReduce
• arguments
 • map: function that emits one or more
    key/value pairs given each object this
  • reduce: function to return aggregate
    result, given key and list of values
 • scope: global variables to set for funcs
• results
 • stored in a temporary collection
    (tmp.mr_1272615772_3)
when were objs created?
> db.tmp.mr_1272615772_3.count()
12
                script was running for 12 minutes
when were objs created?
> db.tmp.mr_1272615772_3.count()
12
                  script was running for 12 minutes


> db.tmp.mr_1272615772_3.find().sort
({value:-1}).limit(1)
{_id: 8, value: 41231}
           41k objects created 8 minutes after start
references to this object?
ary = [“a”,”b”,”c”]
                                     ary references “a”
                                 “b” referenced by ary

 • ruby makes it easy to “leak” references
  • an object will stay around until all
     references to it are gone
   • more objects = longer GC = bad
     performance
 • must find references to fix leaks
references to this object?
•   db.rails_refs.insert({
       _id:"0xary", refs:["0xa","0xb","0xc"]
    })
    create references lookup table
references to this object?
•   db.rails_refs.insert({
       _id:"0xary", refs:["0xa","0xb","0xc"]
    })
    create references lookup table
•   db.rails_refs.ensureIndex({refs:1})
    add ‘multikey’ index to refs array
references to this object?
•   db.rails_refs.insert({
       _id:"0xary", refs:["0xa","0xb","0xc"]
    })
    create references lookup table
•   db.rails_refs.ensureIndex({refs:1})
    add ‘multikey’ index to refs array
•   db.rails_refs.find({refs:“0xa”})
    efficiently lookup all objs holding a ref to 0xa
mongodb: multikeys

• indexes on array values create a ‘multikey’
  index
• classic example: nested array of tags
  •   find({tags: “ruby”})
      find objs where obj.tags includes “ruby”
version 2: memprof.com
   a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
memprof.com
a web-based heap visualizer and leak analyzer
plugging a leak in rails3
• in dev mode, rails3 is leaking 10mb per request
plugging a leak in rails3
• in dev mode, rails3 is leaking 10mb per request

let’s use memprof to find it!

  # in environment.rb
  require `gem which memprof/signal`.strip
plugging a leak
   in rails3
 send the app some
 requests so it leaks
 $ ab -c 1 -n 30
 http://localhost:3000/
plugging a leak
   in rails3
 send the app some
 requests so it leaks
 $ ab -c 1 -n 30
 http://localhost:3000/


 tell memprof to dump
 out the entire heap to
 json
 $ memprof
   --pid <pid>
   --name <dump name>
   --key <api key>
plugging a leak
   in rails3
 send the app some
 requests so it leaks
 $ ab -c 1 -n 30
 http://localhost:3000/


 tell memprof to dump
 out the entire heap to
 json
 $ memprof
   --pid <pid>
   --name <dump name>
   --key <api key>
2519 classes
2519 classes
  30 copies of
TestController
2519 classes
  30 copies of
TestController
2519 classes
  30 copies of
TestController

                 mongo query for all
                 TestController classes
2519 classes
  30 copies of
TestController

                 mongo query for all
                 TestController classes



                 details for one copy of
                 TestController
find references to object
find references to object
find references to object




holding references
 to all controllers
find references to object




 “leak” is on line 178



holding references
 to all controllers
• In development mode, Rails reloads all your
  application code on every request
• In development mode, Rails reloads all your
  application code on every request
• ActionView::Partials::PartialRenderer is caching
  partials used by each controller as an optimization
• In development mode, Rails reloads all your
  application code on every request
• ActionView::Partials::PartialRenderer is caching
  partials used by each controller as an optimization
• But.. it ends up holding a reference to every single
  reloaded version of those controllers
• In development mode, Rails reloads all your
  application code on every request
• ActionView::Partials::PartialRenderer is caching
  partials used by each controller as an optimization
• But.. it ends up holding a reference to every single
  reloaded version of those controllers
Questions?
 Aman Gupta
  @tmm1

Más contenido relacionado

La actualidad más candente

rails-migrations_1
rails-migrations_1rails-migrations_1
rails-migrations_1brecke
 
Inside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source DatabaseInside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source DatabaseMike Dirolf
 
ハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使うハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使うbpstudy
 
Embedding a language into string interpolator
Embedding a language into string interpolatorEmbedding a language into string interpolator
Embedding a language into string interpolatorMichael Limansky
 
Scala Domain Modeling and Architecture
Scala Domain Modeling and ArchitectureScala Domain Modeling and Architecture
Scala Domain Modeling and ArchitectureHossam Karim
 
Mongo db문서의생성,갱신,삭제
Mongo db문서의생성,갱신,삭제Mongo db문서의생성,갱신,삭제
Mongo db문서의생성,갱신,삭제홍준 김
 
Hidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard LibraryHidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard Librarydoughellmann
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance TuningPuneet Behl
 
Map/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBMap/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBUwe Printz
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapHoward Lewis Ship
 
A quick python_tour
A quick python_tourA quick python_tour
A quick python_tourcghtkh
 
Iniciando com jquery
Iniciando com jqueryIniciando com jquery
Iniciando com jqueryDanilo Sousa
 
Advanced geoprocessing with Python
Advanced geoprocessing with PythonAdvanced geoprocessing with Python
Advanced geoprocessing with PythonChad Cooper
 
Error based blind sqli
Error based blind sqliError based blind sqli
Error based blind sqliDarkZtone Zone
 
Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge O T
 
はじめてのMongoDB
はじめてのMongoDBはじめてのMongoDB
はじめてのMongoDBTakahiro Inoue
 

La actualidad más candente (19)

rails-migrations_1
rails-migrations_1rails-migrations_1
rails-migrations_1
 
Inside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source DatabaseInside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source Database
 
ハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使うハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使う
 
Embedding a language into string interpolator
Embedding a language into string interpolatorEmbedding a language into string interpolator
Embedding a language into string interpolator
 
Scala Domain Modeling and Architecture
Scala Domain Modeling and ArchitectureScala Domain Modeling and Architecture
Scala Domain Modeling and Architecture
 
Mongo db문서의생성,갱신,삭제
Mongo db문서의생성,갱신,삭제Mongo db문서의생성,갱신,삭제
Mongo db문서의생성,갱신,삭제
 
Hidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard LibraryHidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard Library
 
Arrays in PHP
Arrays in PHPArrays in PHP
Arrays in PHP
 
Spine JS
Spine JSSpine JS
Spine JS
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance Tuning
 
Map/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBMap/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDB
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
 
A quick python_tour
A quick python_tourA quick python_tour
A quick python_tour
 
Iniciando com jquery
Iniciando com jqueryIniciando com jquery
Iniciando com jquery
 
Indexing
IndexingIndexing
Indexing
 
Advanced geoprocessing with Python
Advanced geoprocessing with PythonAdvanced geoprocessing with Python
Advanced geoprocessing with Python
 
Error based blind sqli
Error based blind sqliError based blind sqli
Error based blind sqli
 
Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge
 
はじめてのMongoDB
はじめてのMongoDBはじめてのMongoDB
はじめてのMongoDB
 

Destacado

Debugging Ruby Systems
Debugging Ruby SystemsDebugging Ruby Systems
Debugging Ruby SystemsEngine Yard
 
Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010Dirkjan Bussink
 
Debugging Ruby
Debugging RubyDebugging Ruby
Debugging RubyAman Gupta
 
OpenSource Hardware -Debian Way
OpenSource Hardware -Debian WayOpenSource Hardware -Debian Way
OpenSource Hardware -Debian WaySiji Sunny
 
Operating OPNFV
Operating OPNFVOperating OPNFV
Operating OPNFVOPNFV
 
OpenStack@Mini-Deb Conf'16 Mumbai
OpenStack@Mini-Deb Conf'16 MumbaiOpenStack@Mini-Deb Conf'16 Mumbai
OpenStack@Mini-Deb Conf'16 MumbaiAkanksha Agrawal
 
Your first patch to OpenStack
Your first patch to OpenStackYour first patch to OpenStack
Your first patch to OpenStackopenstackindia
 
Copr HD OpenStack Day India
Copr HD OpenStack Day IndiaCopr HD OpenStack Day India
Copr HD OpenStack Day Indiaopenstackindia
 
Deploying openstack using ansible
Deploying openstack using ansibleDeploying openstack using ansible
Deploying openstack using ansibleopenstackindia
 
The OpenStack Contribution Workflow
The OpenStack Contribution WorkflowThe OpenStack Contribution Workflow
The OpenStack Contribution Workflowopenstackindia
 
Your first patch to open stack
Your first patch to open stackYour first patch to open stack
Your first patch to open stackAkanksha Agrawal
 
Guts & OpenStack migration
Guts & OpenStack migrationGuts & OpenStack migration
Guts & OpenStack migrationopenstackindia
 
OpenStack Storage Buddy Ceph
OpenStack Storage Buddy CephOpenStack Storage Buddy Ceph
OpenStack Storage Buddy Cephopenstackindia
 
Introduction to tempest
Introduction to tempest Introduction to tempest
Introduction to tempest openstackindia
 
Pgcon2012 ori-20120224
Pgcon2012 ori-20120224Pgcon2012 ori-20120224
Pgcon2012 ori-20120224Manabu Ori
 
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은jieun kim
 
Ryu with OpenFlow 1.3, Traffic Monitor
Ryu with OpenFlow 1.3, Traffic MonitorRyu with OpenFlow 1.3, Traffic Monitor
Ryu with OpenFlow 1.3, Traffic Monitorjieun kim
 
Who carries your container? Zun or Magnum?
Who carries your container? Zun or Magnum?Who carries your container? Zun or Magnum?
Who carries your container? Zun or Magnum?Madhuri Kumari
 

Destacado (20)

Debugging Ruby Systems
Debugging Ruby SystemsDebugging Ruby Systems
Debugging Ruby Systems
 
Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010Rubinius @ RubyAndRails2010
Rubinius @ RubyAndRails2010
 
Debugging Ruby
Debugging RubyDebugging Ruby
Debugging Ruby
 
OpenSource Hardware -Debian Way
OpenSource Hardware -Debian WayOpenSource Hardware -Debian Way
OpenSource Hardware -Debian Way
 
Operating OPNFV
Operating OPNFVOperating OPNFV
Operating OPNFV
 
OpenStack@Mini-Deb Conf'16 Mumbai
OpenStack@Mini-Deb Conf'16 MumbaiOpenStack@Mini-Deb Conf'16 Mumbai
OpenStack@Mini-Deb Conf'16 Mumbai
 
Your first patch to OpenStack
Your first patch to OpenStackYour first patch to OpenStack
Your first patch to OpenStack
 
Copr HD OpenStack Day India
Copr HD OpenStack Day IndiaCopr HD OpenStack Day India
Copr HD OpenStack Day India
 
Deploying openstack using ansible
Deploying openstack using ansibleDeploying openstack using ansible
Deploying openstack using ansible
 
The OpenStack Contribution Workflow
The OpenStack Contribution WorkflowThe OpenStack Contribution Workflow
The OpenStack Contribution Workflow
 
Your first patch to open stack
Your first patch to open stackYour first patch to open stack
Your first patch to open stack
 
Open stack qa and tempest
Open stack qa and tempestOpen stack qa and tempest
Open stack qa and tempest
 
Guts & OpenStack migration
Guts & OpenStack migrationGuts & OpenStack migration
Guts & OpenStack migration
 
OpenStack Storage Buddy Ceph
OpenStack Storage Buddy CephOpenStack Storage Buddy Ceph
OpenStack Storage Buddy Ceph
 
Introduction to tempest
Introduction to tempest Introduction to tempest
Introduction to tempest
 
Pgcon2012 ori-20120224
Pgcon2012 ori-20120224Pgcon2012 ori-20120224
Pgcon2012 ori-20120224
 
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
 
Ryu with OpenFlow 1.3, Traffic Monitor
Ryu with OpenFlow 1.3, Traffic MonitorRyu with OpenFlow 1.3, Traffic Monitor
Ryu with OpenFlow 1.3, Traffic Monitor
 
Who carries your container? Zun or Magnum?
Who carries your container? Zun or Magnum?Who carries your container? Zun or Magnum?
Who carries your container? Zun or Magnum?
 
OPNFV & OpenStack
OPNFV & OpenStackOPNFV & OpenStack
OPNFV & OpenStack
 

Similar a Debugging Ruby (Aman Gupta)

Presentation of Python, Django, DockerStack
Presentation of Python, Django, DockerStackPresentation of Python, Django, DockerStack
Presentation of Python, Django, DockerStackDavid Sanchez
 
Managing Social Content with MongoDB
Managing Social Content with MongoDBManaging Social Content with MongoDB
Managing Social Content with MongoDBMongoDB
 
Forking Oryx at Intalio
Forking Oryx at IntalioForking Oryx at Intalio
Forking Oryx at IntalioAntoine Toulme
 
The Ring programming language version 1.10 book - Part 39 of 212
The Ring programming language version 1.10 book - Part 39 of 212The Ring programming language version 1.10 book - Part 39 of 212
The Ring programming language version 1.10 book - Part 39 of 212Mahmoud Samir Fayed
 
Webinar: Strongly Typed Languages and Flexible Schemas
Webinar: Strongly Typed Languages and Flexible SchemasWebinar: Strongly Typed Languages and Flexible Schemas
Webinar: Strongly Typed Languages and Flexible SchemasMongoDB
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayUtkarsh Sengar
 
Strongly Typed Languages and Flexible Schemas
Strongly Typed Languages and Flexible SchemasStrongly Typed Languages and Flexible Schemas
Strongly Typed Languages and Flexible SchemasNorberto Leite
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to PythonUC San Diego
 
d3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in Berlind3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in BerlinToshiaki Katayama
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDCMike Dirolf
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7decoupled
 
Computational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data WranglingComputational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data Wranglingjakehofman
 

Similar a Debugging Ruby (Aman Gupta) (20)

Presentation of Python, Django, DockerStack
Presentation of Python, Django, DockerStackPresentation of Python, Django, DockerStack
Presentation of Python, Django, DockerStack
 
Managing Social Content with MongoDB
Managing Social Content with MongoDBManaging Social Content with MongoDB
Managing Social Content with MongoDB
 
Forking Oryx at Intalio
Forking Oryx at IntalioForking Oryx at Intalio
Forking Oryx at Intalio
 
Struktur data 1
Struktur data 1Struktur data 1
Struktur data 1
 
Intro to Python
Intro to PythonIntro to Python
Intro to Python
 
The Ring programming language version 1.10 book - Part 39 of 212
The Ring programming language version 1.10 book - Part 39 of 212The Ring programming language version 1.10 book - Part 39 of 212
The Ring programming language version 1.10 book - Part 39 of 212
 
Webinar: Strongly Typed Languages and Flexible Schemas
Webinar: Strongly Typed Languages and Flexible SchemasWebinar: Strongly Typed Languages and Flexible Schemas
Webinar: Strongly Typed Languages and Flexible Schemas
 
Mongo db presentation
Mongo db presentationMongo db presentation
Mongo db presentation
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
 
CouchDB-Lucene
CouchDB-LuceneCouchDB-Lucene
CouchDB-Lucene
 
Latinoware
LatinowareLatinoware
Latinoware
 
Strongly Typed Languages and Flexible Schemas
Strongly Typed Languages and Flexible SchemasStrongly Typed Languages and Flexible Schemas
Strongly Typed Languages and Flexible Schemas
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
d3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in Berlind3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in Berlin
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDC
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
Net framework
Net frameworkNet framework
Net framework
 
Computational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data WranglingComputational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data Wrangling
 
SVGo workshop
SVGo workshopSVGo workshop
SVGo workshop
 

Más de MongoSF

Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) MongoSF
 
Schema design with MongoDB (Dwight Merriman)
Schema design with MongoDB (Dwight Merriman)Schema design with MongoDB (Dwight Merriman)
Schema design with MongoDB (Dwight Merriman)MongoSF
 
C# Development (Sam Corder)
C# Development (Sam Corder)C# Development (Sam Corder)
C# Development (Sam Corder)MongoSF
 
Flexible Event Tracking (Paul Gebheim)
Flexible Event Tracking (Paul Gebheim)Flexible Event Tracking (Paul Gebheim)
Flexible Event Tracking (Paul Gebheim)MongoSF
 
Administration (Eliot Horowitz)
Administration (Eliot Horowitz)Administration (Eliot Horowitz)
Administration (Eliot Horowitz)MongoSF
 
MongoHQ (Jason McCay & Ben Wyrosdick)
MongoHQ (Jason McCay & Ben Wyrosdick)MongoHQ (Jason McCay & Ben Wyrosdick)
MongoHQ (Jason McCay & Ben Wyrosdick)MongoSF
 
Administration
AdministrationAdministration
AdministrationMongoSF
 
Sharding with MongoDB (Eliot Horowitz)
Sharding with MongoDB (Eliot Horowitz)Sharding with MongoDB (Eliot Horowitz)
Sharding with MongoDB (Eliot Horowitz)MongoSF
 
Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)MongoSF
 
Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)MongoSF
 
Indexing and Query Optimizer (Aaron Staple)
Indexing and Query Optimizer (Aaron Staple)Indexing and Query Optimizer (Aaron Staple)
Indexing and Query Optimizer (Aaron Staple)MongoSF
 
MongoDB Replication (Dwight Merriman)
MongoDB Replication (Dwight Merriman)MongoDB Replication (Dwight Merriman)
MongoDB Replication (Dwight Merriman)MongoSF
 
Zero to Mongo in 60 Hours
Zero to Mongo in 60 HoursZero to Mongo in 60 Hours
Zero to Mongo in 60 HoursMongoSF
 
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)MongoSF
 
PHP Development with MongoDB (Fitz Agard)
PHP Development with MongoDB (Fitz Agard)PHP Development with MongoDB (Fitz Agard)
PHP Development with MongoDB (Fitz Agard)MongoSF
 
Java Development with MongoDB (James Williams)
Java Development with MongoDB (James Williams)Java Development with MongoDB (James Williams)
Java Development with MongoDB (James Williams)MongoSF
 
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...MongoSF
 
From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)MongoSF
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)MongoSF
 

Más de MongoSF (19)

Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
Webinar: Typische MongoDB Anwendungsfälle (Common MongoDB Use Cases) 
 
Schema design with MongoDB (Dwight Merriman)
Schema design with MongoDB (Dwight Merriman)Schema design with MongoDB (Dwight Merriman)
Schema design with MongoDB (Dwight Merriman)
 
C# Development (Sam Corder)
C# Development (Sam Corder)C# Development (Sam Corder)
C# Development (Sam Corder)
 
Flexible Event Tracking (Paul Gebheim)
Flexible Event Tracking (Paul Gebheim)Flexible Event Tracking (Paul Gebheim)
Flexible Event Tracking (Paul Gebheim)
 
Administration (Eliot Horowitz)
Administration (Eliot Horowitz)Administration (Eliot Horowitz)
Administration (Eliot Horowitz)
 
MongoHQ (Jason McCay & Ben Wyrosdick)
MongoHQ (Jason McCay & Ben Wyrosdick)MongoHQ (Jason McCay & Ben Wyrosdick)
MongoHQ (Jason McCay & Ben Wyrosdick)
 
Administration
AdministrationAdministration
Administration
 
Sharding with MongoDB (Eliot Horowitz)
Sharding with MongoDB (Eliot Horowitz)Sharding with MongoDB (Eliot Horowitz)
Sharding with MongoDB (Eliot Horowitz)
 
Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)
 
Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)
 
Indexing and Query Optimizer (Aaron Staple)
Indexing and Query Optimizer (Aaron Staple)Indexing and Query Optimizer (Aaron Staple)
Indexing and Query Optimizer (Aaron Staple)
 
MongoDB Replication (Dwight Merriman)
MongoDB Replication (Dwight Merriman)MongoDB Replication (Dwight Merriman)
MongoDB Replication (Dwight Merriman)
 
Zero to Mongo in 60 Hours
Zero to Mongo in 60 HoursZero to Mongo in 60 Hours
Zero to Mongo in 60 Hours
 
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
Building a Mongo DSL in Scala at Hot Potato (Lincoln Hochberg)
 
PHP Development with MongoDB (Fitz Agard)
PHP Development with MongoDB (Fitz Agard)PHP Development with MongoDB (Fitz Agard)
PHP Development with MongoDB (Fitz Agard)
 
Java Development with MongoDB (James Williams)
Java Development with MongoDB (James Williams)Java Development with MongoDB (James Williams)
Java Development with MongoDB (James Williams)
 
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
Real time ecommerce analytics with MongoDB at Gilt Groupe (Michael Bryzek & M...
 
From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
 

Último

Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfAarwolf Industries LLC
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 

Último (20)

Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdf
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 

Debugging Ruby (Aman Gupta)

  • 1. Debugging Ruby with MongoDB Aman Gupta @tmm1
  • 3. debugging ruby? • i use ruby • my ruby processes use a lot of ram
  • 4. debugging ruby? • i use ruby • my ruby processes use a lot of ram • i want to fix this
  • 5. let’s build a debugger • step 1: collect data • list of all ruby objects in memory
  • 6. let’s build a debugger • step 1: collect data • list of all ruby objects in memory • step 2: analyze data • group by type • group by file/line
  • 7. version 1: collect data • simple patch to ruby VM (300 lines of C) • http://gist.github.com/73674 • simple text based output format 0x154750 @ -e:1 is OBJECT of type: T 0x15476c @ -e:1 is HASH which has data 0x154788 @ -e:1 is ARRAY of len: 0 0x1547c0 @ -e:1 is STRING (SHARED) len: 2 and val: hi 0x1547dc @ -e:1 is STRING len: 1 and val: T 0x154814 @ -e:1 is CLASS named: T inherits from Object 0x154a98 @ -e:1 is STRING len: 2 and val: hi 0x154b40 @ -e:1 is OBJECT of type: Range
  • 8. version 1: analyze data $ wc -l /tmp/ruby.heap  1571529 /tmp/ruby.heap
  • 9. version 1: analyze data $ wc -l /tmp/ruby.heap  1571529 /tmp/ruby.heap $ cat /tmp/ruby.heap | awk '{ print $3 }' | sort | uniq -c | sort -g | tail -1  236840 memcached/memcached.rb:316
  • 10. version 1: analyze data $ wc -l /tmp/ruby.heap  1571529 /tmp/ruby.heap $ cat /tmp/ruby.heap | awk '{ print $3 }' | sort | uniq -c | sort -g | tail -1  236840 memcached/memcached.rb:316 $ grep "memcached.rb:316" /tmp/ruby.heap | awk '{ print $5 }' | sort | uniq -c | sort -g | tail -5    10948 ARRAY    20355 OBJECT    30744 DATA   64952 HASH   123290 STRING
  • 13. version 1 • it works! • but...
  • 14. version 1 • it works! • but... • must patch and rebuild ruby binary
  • 15. version 1 • it works! • but... • must patch and rebuild ruby binary • no information about references between objects
  • 16. version 1 • it works! • but... • must patch and rebuild ruby binary • no information about references between objects • limited analysis via shell scripting
  • 18. version 2 goals • better data format
  • 19. version 2 goals • better data format • simple: one line of text per object
  • 20. version 2 goals • better data format • simple: one line of text per object • expressive: include all details about object contents and references
  • 21. version 2 goals • better data format • simple: one line of text per object • expressive: include all details about object contents and references • easy to use: easy to generate from C code & easy to consume from various scripting languages
  • 22. JSON!
  • 23. version 2 is memprof
  • 24. version 2 is memprof • no patches to ruby necessary • gem install memprof • require ‘memprof’ • Memprof.dump_all(“/tmp/app.json”)
  • 25. version 2 is memprof • no patches to ruby necessary • gem install memprof • require ‘memprof’ • Memprof.dump_all(“/tmp/app.json”) • C extension for MRI ruby VM http://github.com/ice799/memprof • uses libyajl to dump out all ruby objects as json
  • 26. Memprof.dump{ strings } “hello” + “world”
  • 27. Memprof.dump{ strings } “hello” + “world” { "_id": "0x19c610", memory address of object "file": "-e", "line": 1, "type": "string", "class": "0x1ba7f0", "class_name": "String", "length": 10, "data": "helloworld" }
  • 28. Memprof.dump{ strings } “hello” + “world” { "_id": "0x19c610", memory address of object "file": "-e", file and line where string "line": 1, was created "type": "string", "class": "0x1ba7f0", "class_name": "String", "length": 10, "data": "helloworld" }
  • 29. Memprof.dump{ strings } “hello” + “world” { "_id": "0x19c610", memory address of object "file": "-e", file and line where string "line": 1, was created "type": "string", "class": "0x1ba7f0", address of the class object "class_name": "String", “String” "length": 10, "data": "helloworld" }
  • 30. Memprof.dump{ strings } “hello” + “world” { "_id": "0x19c610", memory address of object "file": "-e", file and line where string "line": 1, was created "type": "string", "class": "0x1ba7f0", address of the class object "class_name": "String", “String” "length": 10, length and contents "data": "helloworld" of this string instance }
  • 31. arrays Memprof.dump{ [ 1, :b, 2.2, “d” ] }
  • 32. arrays Memprof.dump{ [ 1, :b, { "_id": "0x19c5c0", 2.2, “d” "class": "0x1b0d18", ] "class_name": "Array", } "length": 4, "data": [ 1, ":b", "0x19c750", "0x19c598" ] }
  • 33. arrays Memprof.dump{ [ 1, :b, { "_id": "0x19c5c0", 2.2, “d” "class": "0x1b0d18", ] "class_name": "Array", } "length": 4, "data": [ 1, integers and symbols are ":b", stored in the array itself "0x19c750", "0x19c598" ] }
  • 34. arrays Memprof.dump{ [ 1, :b, { "_id": "0x19c5c0", 2.2, “d” "class": "0x1b0d18", ] "class_name": "Array", } "length": 4, "data": [ 1, integers and symbols are ":b", stored in the array itself "0x19c750", floats and strings are "0x19c598" separate ruby objects ] }
  • 35. hashes Memprof.dump{ { :a => 1, “b” => 2.2 } }
  • 36. hashes Memprof.dump{ { :a => 1, “b” => 2.2 { } "_id": "0x19c598", } "type": "hash", "class": "0x1af170", "class_name": "Hash", "default": null, "length": 2, "data": [ [ ":a", 1 ], [ "0xc728", "0xc750" ] ] }
  • 37. hashes Memprof.dump{ { :a => 1, “b” => 2.2 { } "_id": "0x19c598", } "type": "hash", "class": "0x1af170", "class_name": "Hash", "default": null, "length": 2, "data": [ [ ":a", 1 ], hash entries as key/value [ "0xc728", "0xc750" ] pairs ] }
  • 38. hashes Memprof.dump{ { :a => 1, “b” => 2.2 { } "_id": "0x19c598", } "type": "hash", "class": "0x1af170", "class_name": "Hash", "default": null, no default proc "length": 2, "data": [ [ ":a", 1 ], hash entries as key/value [ "0xc728", "0xc750" ] pairs ] }
  • 39. classes Memprof.dump{ class Hello @@var=1 Const=2 def world() end end }
  • 40. classes Memprof.dump{ class Hello @@var=1 Const=2 { def world() end "_id": "0x19c408", end "type": "class", } "name": "Hello", "super": "0x1bfa48", "super_name": "Object", "ivars": { "@@var": 1, "Const": 2 }, "methods": { "world": "0x19c318" } }
  • 41. classes Memprof.dump{ class Hello @@var=1 Const=2 { def world() end "_id": "0x19c408", end "type": "class", } "name": "Hello", "super": "0x1bfa48", superclass object reference "super_name": "Object", "ivars": { "@@var": 1, "Const": 2 }, "methods": { "world": "0x19c318" } }
  • 42. classes Memprof.dump{ class Hello @@var=1 Const=2 { def world() end "_id": "0x19c408", end "type": "class", } "name": "Hello", "super": "0x1bfa48", superclass object reference "super_name": "Object", "ivars": { class variables and constants "@@var": 1, are stored in the instance "Const": 2 }, variable table "methods": { "world": "0x19c318" } }
  • 43. classes Memprof.dump{ class Hello @@var=1 Const=2 { def world() end "_id": "0x19c408", end "type": "class", } "name": "Hello", "super": "0x1bfa48", superclass object reference "super_name": "Object", "ivars": { class variables and constants "@@var": 1, are stored in the instance "Const": 2 }, variable table "methods": { "world": "0x19c318" references to method objects } }
  • 45. version 2: memprof.com a web-based heap visualizer and leak analyzer
  • 47. built on... $ mongoimport -d memprof -c rails --file /tmp/app.json $ mongo memprof
  • 48. built on... $ mongoimport -d memprof -c rails --file /tmp/app.json $ mongo memprof let’s run some queries.
  • 49. how many objects? > db.rails.count() 809816 • ruby scripts create a lot of objects • usually not a problem, but... • MRI has a naïve stop-the-world mark/ sweep GC • fewer objects = faster GC = better performance
  • 50. what types of objects? > db.rails.distinct(‘type’) [‘array’, ‘bignum’, ‘class’, ‘float’, ‘hash’, ‘module’, ‘node’, ‘object’, ‘regexp’, ‘string’, ...]
  • 52. mongodb: distinct • distinct(‘type’) list of types of objects
  • 53. mongodb: distinct • distinct(‘type’) list of types of objects • distinct(‘file’) list of source files
  • 54. mongodb: distinct • distinct(‘type’) list of types of objects • distinct(‘file’) list of source files • distinct(‘class_name’) list of instance class names
  • 55. mongodb: distinct • distinct(‘type’) list of types of objects • distinct(‘file’) list of source files • distinct(‘class_name’) list of instance class names • optionally filter first • distinct(‘name’, {type:“class”}) names of all defined classes
  • 56. improve performance with indexes > db.rails.ensureIndex({‘type’:1})
  • 57. improve performance with indexes > db.rails.ensureIndex({‘type’:1}) > db.rails.ensureIndex( {‘file’:1}, {background:true} )
  • 58. mongodb: ensureIndex • add an index on a field (if it doesn’t exist yet) • improve performance of queries against common fields: type, class_name, super, file
  • 59. mongodb: ensureIndex • add an index on a field (if it doesn’t exist yet) • improve performance of queries against common fields: type, class_name, super, file • can index embedded field names • ensureIndex(‘methods.add’) • find({‘methods.add’:{$exists:true}}) find classes that define the method add
  • 60. how many objs per type? > db.rails.group({ initial: {count:0}, key: {type:true}, group on type cond: {}, reduce: function(obj, out) { out.count++ } }).sort(function(a,b){ return a.count - b.count })
  • 61. how many objs per type? > db.rails.group({ initial: {count:0}, key: {type:true}, group on type cond: {}, reduce: function(obj, out) { increment count out.count++ for each obj } }).sort(function(a,b){ return a.count - b.count })
  • 62. how many objs per type? > db.rails.group({ initial: {count:0}, key: {type:true}, group on type cond: {}, reduce: function(obj, out) { increment count out.count++ for each obj } }).sort(function(a,b){ return a.count - b.count sort results })
  • 63. how many objs per type? [ ..., {type: ‘array’, count: 7621}, {type: ‘string’, count: 69139}, {type: ‘node’, count: 365285} ]
  • 64. how many objs per type? [ ..., {type: ‘array’, count: 7621}, {type: ‘string’, count: 69139}, {type: ‘node’, count: 365285} ] lots of nodes
  • 65. how many objs per type? [ ..., {type: ‘array’, count: 7621}, {type: ‘string’, count: 69139}, {type: ‘node’, count: 365285} ] lots of nodes • nodes represent ruby code • stored like any other ruby object • makes ruby completely dynamic
  • 67. mongodb: group • cond: query to filter objects before grouping
  • 68. mongodb: group • cond: query to filter objects before grouping • key: field(s) to group on
  • 69. mongodb: group • cond: query to filter objects before grouping • key: field(s) to group on • initial: initial values for each group’s results
  • 70. mongodb: group • cond: query to filter objects before grouping • key: field(s) to group on • initial: initial values for each group’s results • reduce: aggregation function
  • 72. mongodb: group • bykey: {type:1} type or class • • key: {class_name:1}
  • 73. mongodb: group • bykey: {type:1} type or class • • key: {class_name:1} • bykey:&{file:1, line:1} file line •
  • 74. mongodb: group • bykey: {type:1} type or class • • key: {class_name:1} • bykey:&{file:1, line:1} file line • • bycond: in a specific file type • {file: “app.rb”}, key: {file:1, line:1}
  • 75. mongodb: group • bykey: {type:1} type or class • • key: {class_name:1} • bykey:&{file:1, line:1} file line • • bycond: in a specific file type • {file: “app.rb”}, key: {file:1, line:1} • bycond: {file:“app.rb”,type:‘string’}, length of strings in a specific file • key: {length:1}
  • 76. what subclasses String? > db.rails.find( {super_name:"String"}, {name:1} ) {name: "ActiveSupport::SafeBuffer"} {name: "ActiveSupport::StringInquirer"} {name: "SQLite3::Blob"} {name: "ActiveModel::Name"} {name: "Arel::Attribute::Expressions"} {name: "ActiveSupport::JSON::Variable"}
  • 77. what subclasses String? > db.rails.find( {super_name:"String"}, {name:1} select only name field ) {name: "ActiveSupport::SafeBuffer"} {name: "ActiveSupport::StringInquirer"} {name: "SQLite3::Blob"} {name: "ActiveModel::Name"} {name: "Arel::Attribute::Expressions"} {name: "ActiveSupport::JSON::Variable"}
  • 79. mongodb: find • find({type:‘string’}) all strings
  • 80. mongodb: find • find({type:‘string’}) all strings • find({type:{$ne:‘string’}}) everything except strings
  • 81. mongodb: find • find({type:‘string’}) all strings • find({type:{$ne:‘string’}}) everything except strings • find({type:‘string’}, {data:1}) only select string’s data field
  • 82. the largest objects? > db.rails.find( {type: {$in:['string','array','hash']} }, {type:1,length:1} ).sort({length:-1}).limit(3) {type: "string", length: 2308} {type: "string", length: 1454} {type: "string", length: 1238}
  • 84. mongodb: sort, limit/skip • sort({length:-1,file:1}) sort by length desc, file asc
  • 85. mongodb: sort, limit/skip • sort({length:-1,file:1}) sort by length desc, file asc • limit(10) first 10 results
  • 86. mongodb: sort, limit/skip • sort({length:-1,file:1}) sort by length desc, file asc • limit(10) first 10 results • skip(10).limit(10) second 10 results
  • 87. when were objs created? • useful to look at objects over time • each obj has a timestamp of when it was created
  • 88. when were objs created? • useful to look at objects over time • each obj has a timestamp of when it was created • find minimum time, call it start_time
  • 89. when were objs created? • useful to look at objects over time • each obj has a timestamp of when it was created • find minimum time, call it start_time • create buckets for every minute of execution since start
  • 90. when were objs created? • useful to look at objects over time • each obj has a timestamp of when it was created • find minimum time, call it start_time • create buckets for every minute of execution since start • place objects into buckets
  • 91. when were objs created? > db.rails.mapReduce(function(){ var secs = this.time - start_time; var mins_since_start = secs % 60; emit(mins_since_start, 1); }, function(key, vals){ for(var i=0,sum=0; i<vals.length; sum += vals[i++]); return sum; }, { scope: { start_time: db.rails.find ().sort({time:1}).limit(1)[0].time } } start_time = min(time) ) {result:"tmp.mr_1272615772_3"}
  • 92. mongodb: mapReduce • arguments • map: function that emits one or more key/value pairs given each object this • reduce: function to return aggregate result, given key and list of values • scope: global variables to set for funcs
  • 93. mongodb: mapReduce • arguments • map: function that emits one or more key/value pairs given each object this • reduce: function to return aggregate result, given key and list of values • scope: global variables to set for funcs • results • stored in a temporary collection (tmp.mr_1272615772_3)
  • 94. when were objs created? > db.tmp.mr_1272615772_3.count() 12 script was running for 12 minutes
  • 95. when were objs created? > db.tmp.mr_1272615772_3.count() 12 script was running for 12 minutes > db.tmp.mr_1272615772_3.find().sort ({value:-1}).limit(1) {_id: 8, value: 41231} 41k objects created 8 minutes after start
  • 96. references to this object? ary = [“a”,”b”,”c”] ary references “a” “b” referenced by ary • ruby makes it easy to “leak” references • an object will stay around until all references to it are gone • more objects = longer GC = bad performance • must find references to fix leaks
  • 97. references to this object? • db.rails_refs.insert({ _id:"0xary", refs:["0xa","0xb","0xc"] }) create references lookup table
  • 98. references to this object? • db.rails_refs.insert({ _id:"0xary", refs:["0xa","0xb","0xc"] }) create references lookup table • db.rails_refs.ensureIndex({refs:1}) add ‘multikey’ index to refs array
  • 99. references to this object? • db.rails_refs.insert({ _id:"0xary", refs:["0xa","0xb","0xc"] }) create references lookup table • db.rails_refs.ensureIndex({refs:1}) add ‘multikey’ index to refs array • db.rails_refs.find({refs:“0xa”}) efficiently lookup all objs holding a ref to 0xa
  • 100. mongodb: multikeys • indexes on array values create a ‘multikey’ index • classic example: nested array of tags • find({tags: “ruby”}) find objs where obj.tags includes “ruby”
  • 101. version 2: memprof.com a web-based heap visualizer and leak analyzer
  • 102. memprof.com a web-based heap visualizer and leak analyzer
  • 103. memprof.com a web-based heap visualizer and leak analyzer
  • 104. memprof.com a web-based heap visualizer and leak analyzer
  • 105. memprof.com a web-based heap visualizer and leak analyzer
  • 106. memprof.com a web-based heap visualizer and leak analyzer
  • 107. memprof.com a web-based heap visualizer and leak analyzer
  • 108. memprof.com a web-based heap visualizer and leak analyzer
  • 109. memprof.com a web-based heap visualizer and leak analyzer
  • 110. memprof.com a web-based heap visualizer and leak analyzer
  • 111. plugging a leak in rails3 • in dev mode, rails3 is leaking 10mb per request
  • 112. plugging a leak in rails3 • in dev mode, rails3 is leaking 10mb per request let’s use memprof to find it! # in environment.rb require `gem which memprof/signal`.strip
  • 113. plugging a leak in rails3 send the app some requests so it leaks $ ab -c 1 -n 30 http://localhost:3000/
  • 114. plugging a leak in rails3 send the app some requests so it leaks $ ab -c 1 -n 30 http://localhost:3000/ tell memprof to dump out the entire heap to json $ memprof --pid <pid> --name <dump name> --key <api key>
  • 115. plugging a leak in rails3 send the app some requests so it leaks $ ab -c 1 -n 30 http://localhost:3000/ tell memprof to dump out the entire heap to json $ memprof --pid <pid> --name <dump name> --key <api key>
  • 116.
  • 118. 2519 classes 30 copies of TestController
  • 119. 2519 classes 30 copies of TestController
  • 120. 2519 classes 30 copies of TestController mongo query for all TestController classes
  • 121. 2519 classes 30 copies of TestController mongo query for all TestController classes details for one copy of TestController
  • 122.
  • 125. find references to object holding references to all controllers
  • 126. find references to object “leak” is on line 178 holding references to all controllers
  • 127. • In development mode, Rails reloads all your application code on every request
  • 128. • In development mode, Rails reloads all your application code on every request • ActionView::Partials::PartialRenderer is caching partials used by each controller as an optimization
  • 129. • In development mode, Rails reloads all your application code on every request • ActionView::Partials::PartialRenderer is caching partials used by each controller as an optimization • But.. it ends up holding a reference to every single reloaded version of those controllers
  • 130. • In development mode, Rails reloads all your application code on every request • ActionView::Partials::PartialRenderer is caching partials used by each controller as an optimization • But.. it ends up holding a reference to every single reloaded version of those controllers