Skip to content

Instantly share code, notes, and snippets.

@tenderlove
Created October 10, 2018 19:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tenderlove/2e57f7ae2a10d5fa76b53273feae84af to your computer and use it in GitHub Desktop.
Save tenderlove/2e57f7ae2a10d5fa76b53273feae84af to your computer and use it in GitHub Desktop.
# extract dead objects from the heap
require 'json'
require 'set'
class Slot
attr_reader :info, :address_to_slot
def initialize info, address_to_slot
@info = info
@address_to_slot = address_to_slot
@marked = false
end
def mark!
@marked = true
end
def references
@references ||= (info[__method__.to_s] || []).uniq.map { |a|
address_to_slot[a]
}.compact
end
def address; info[__method__.to_s]; end
def root; info[__method__.to_s]; end
def root?; info["type"] == "ROOT"; end
def marked?; @marked; end
def id; root? ? root : address; end
end
address_to_slot = {}
roots = []
all_nodes = []
File.open(ARGV.shift, 'r') do |f|
f.each_line do |line|
info = JSON.parse line
slot = Slot.new info, address_to_slot
all_nodes << slot
if slot.root?
roots << slot
else
address_to_slot[slot.address] = slot
end
end
end
def mark mark_stack
seen = Set.new
while obj = mark_stack.pop
next if seen.include? obj
seen << obj
obj.mark!
mark_stack.concat obj.references
end
end
mark roots.dup
garbage = all_nodes.reject(&:marked?)
garbage.each do |g|
puts JSON.dump(g.info)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment