Skip to content

Instantly share code, notes, and snippets.

@ivoanjo
Created March 9, 2015 10:38
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 ivoanjo/4a38ad3812054b0018c9 to your computer and use it in GitHub Desktop.
Save ivoanjo/4a38ad3812054b0018c9 to your computer and use it in GitHub Desktop.
Simple ruby heap dump json navigator
#!/usr/bin/env ruby
# encoding: utf-8
require 'pry'
require 'json'
require 'awesome_print'
AP_OPTIONS = {indent: 2, index: false, multiline: false}
def load_heap(file)
file.collect do |l|
process_dump_line(l)
end.compact
end
def process_dump_line(line)
symbolize_keys(JSON.load(line))
rescue JSON::ParserError => e
puts "Error parsing line: #{e.message}"
nil
end
def symbolize_keys(hash)
hash.inject({}) do |result, (key, value)|
result.update(key.to_sym => value)
end
end
def class_names(heap_classes)
heap_classes.inject({}) do |result, elem|
result.update(elem[:class] => elem[:name])
end
end
def heap_by_type(heap)
heap.inject(Hash.new{[]}) do |result, elem|
type = elem[:type].downcase.to_sym
result.update(type => result[type] << elem)
end
end
def address_map(heap)
heap.inject({}) do |result, elem|
result.update(elem[:address] => elem)
end
end
def sort_by_memsize(heap_objects)
heap_objects.sort_by { |elem| -(elem[:memsize] || 0) }
end
def print_elem(elem)
ap(elem, AP_OPTIONS)
end
puts "Heap navigator loading #{ARGV[0]}"
file = if ARGV[0].end_with?('.gz')
Zlib::GzipReader.open(ARGV[0])
else
File.open(ARGV[0])
end
HEAP = load_heap(file)
HEAP_BY_TYPE = heap_by_type(HEAP)
CLASS_NAMES = class_names(HEAP_BY_TYPE[:class])
HEAP_BY_SIZE = sort_by_memsize(HEAP)
HEAP_BY_ADDRESS = address_map(HEAP)
puts "Heap loaded"
puts
puts "Largest instances:"
HEAP_BY_SIZE[0...10].each { |e| print_elem(e) }
Pry.start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment