Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Breadth-first search of memprof heap dump
require 'progressbar'
require 'shellwords'
require 'json'
require 'active_support/core_ext/hash/keys'
require 'set'
require 'thread' # queue
def main
objs = load_objs
$objs = objs
# These object_ids identify ActiveRecord::Relations from the article
# table which I'm presuming are the ones that are leaked. I had to find
# them in the memprof dump because when I compare
# ObjectSpace.each_object(ActiveRecord::Relation) before and after
# app.get("/"), the object_ids have a different format than those in the
# dump.
oids = Set.new ["0x508d418", "0x5413830"]
path = search_for(objs, oids)
p path
end
def load_objs
filename = "myapp_heap.json"
line_count = `wc -l #{filename.shellescape}`.strip.to_i
bar = ProgressBar.new "Reading json", line_count
objs = {}
File.foreach("myapp_heap.json") do |line|
obj = JSON.parse(line)
obj.symbolize_keys!
objs[obj[:_id]] = obj
bar.inc
end
bar.finish
objs
end
def search_for(objs, target_oids)
queue = Queue.new
$queue = queue
seen = Set.new
queue.enq ["globals"] # initial
until queue.empty?
path = queue.deq
oid = path.last
$stdout.write "#{oid} depth: #{path.length} / queued: #{queue.length} / seen: #{seen.length} \r"
next if seen.include? oid
seen.add oid
if target_oids.include? oid
return path
end
(ch=child_oids(objs[oid])).each do |child|
child_path = path.dup
child_path.push child
queue.enq child_path
end
end
puts
end
def child_oids(obj)
# Perhaps I'm missing some cases here... ?
case obj
when String
if /\A0x[0-9a-f]{1,16}\Z/.match obj
[obj]
else
[]
end
when Array
obj.map {|v| child_oids(v) }.inject([], &:+)
when Hash
obj.map {|k, v| child_oids(v) }.inject([], &:+)
else
[]
end
end
if File.identical?(__FILE__, $0)
main
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.