您当前的位置: 首页 >  ruby

Ruby 2.1: objspace.so

发布时间:2014-12-02 21:22:22 ,浏览量:0

26 Dec 2013

ObjectSpace in ruby contains many useful heap debugging utilities.

Since 1.9 ruby has included  objspace.so which adds even more methods to the ObjectSpace module: 

ObjectSpace.each_object{ |o| ... } ObjectSpace.count_objects #=> {:TOTAL=>55298, :FREE=>10289, :T_OBJECT=>3371, ...} require 'objspace' ObjectSpace.memsize_of(o) #=> 0 /* additional bytes allocated by object */ ObjectSpace.count_tdata_objects #=> {Encoding=>100, Time=>87, RubyVM::Env=>17, ...} ObjectSpace.count_nodes #=> {:NODE_SCOPE=>2, :NODE_BLOCK=>688, :NODE_IF=>9, ...} ObjectSpace.reachable_objects_from(o) #=> [referenced, objects, ...] ObjectSpace.reachable_objects_from_root #=> {"symbols"=>..., "global_tbl"=>...} /* in 2.1 */ 

In 2.1, we've added a two big new features: an allocation tracer and a heap dumper.

Allocation Tracing

Tracking down memory growth and object reference leaks is tricky when you don't know where the objects are coming from.

With 2.1, you can enable allocation tracing to collect metadata about every new object:

require 'objspace' ObjectSpace.trace_object_allocations_start class MyApp def perform "foobar" end end o = MyApp.new.perform ObjectSpace.allocation_sourcefile(o) #=> "example.rb" ObjectSpace.allocation_sourceline(o) #=> 6 ObjectSpace.allocation_generation(o) #=> 1 ObjectSpace.allocation_class_path(o) #=> "MyApp" ObjectSpace.allocation_method_id(o) #=> :perform 

A block version of the tracer is  also available . 

Under the hood, this feature is built on  NEWOBJ and  FREEOBJ tracepoints included in 2.1. These events are only available from C, via rb_tracepoint_new() . 

Heap Dumping

To further help debug object reference leaks, you can dump an object (or the entire heap) for offline analysis.

require 'objspace' # enable tracing for file/line/generation data in dumps ObjectSpace.trace_object_allocations_start # dump single object as json string ObjectSpace.dump("abc".freeze) #=> "{...}" # dump out all live objects to a json file GC.start ObjectSpace.dump_all(output: File.open('heap.json','w')) 

Objects are serialized as simple json, and include all relevant details about the object, its source (if allocating tracing was enabled), and outbound references:

{ "address":"0x007fe9232d5488", "type":"STRING", "class":"0x007fe923029658", "frozen":true, "embedded":true, "fstring":true, "bytesize":3, "value":"abc", "encoding":"UTF-8", "references":[], "file":"irb/workspace.rb", "line":86, "method":"eval", "generation":15, "flags":{"wb_protected":true} } 

The heap dump produced by  ObjectSpace.dump_all can be processed by the tool of your choice. You might try a  json processor like jq or a  json database . Since the dump contains outbound references for each object, a full object graph can be re-created for deep analysis. 

For example, here's a simple ruby/shell script to see which gems/libraries create the most long-lived objects of different types:

$ cat heap.json |  ruby -rjson -ne ' puts JSON.parse($_).values_at("file","line","type").join(":") ' |  sort        |  uniq -c     |  sort -n     |  tail -4 26289 lib/active_support/dependencies.rb:184:NODE 29972 lib/active_support/dependencies.rb:184:DATA 43100 lib/psych/visitors/to_ruby.rb:324:STRING 47096 lib/active_support/dependencies.rb:184:STRING 

If you have a ruby application that feels large or bloated, give these new ObjectSpace features a try. And if you end up writing a heap analysis tool  or visualization for these json files, do let me know  on twitter .

关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    107949博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0484s