Created
October 10, 2018 19:47
-
-
Save tenderlove/2e57f7ae2a10d5fa76b53273feae84af to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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