20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/heapy/analyzer.rb', line 20
def drill_down(generation_to_inspect)
puts ""
puts "Analyzing Heap (Generation: #{generation_to_inspect})"
puts "-------------------------------"
puts ""
generation_to_inspect = Integer(generation_to_inspect) unless generation_to_inspect == "all"
memsize_hash = Hash.new { |h, k| h[k] = 0 }
count_hash = Hash.new { |h, k| h[k] = 0 }
string_count = Hash.new { |h, k| h[k] = Hash.new { |h, k| h[k] = 0 } }
reference_hash = Hash.new { |h, k| h[k] = 0 }
read do |parsed|
generation = parsed["generation"] || 0
if generation_to_inspect == "all".freeze || generation == generation_to_inspect
next unless parsed["file"]
key = "#{ parsed["file"] }:#{ parsed["line"] }"
memsize_hash[key] += parsed["memsize"] || 0
count_hash[key] += 1
if parsed["type"] == "STRING".freeze
string_count[parsed["value"]][key] += 1 if parsed["value"]
end
if parsed["references"]
reference_hash[key] += parsed["references"].length
end
end
end
raise "not a valid Generation: #{generation_to_inspect.inspect}" if memsize_hash.empty?
total_memsize = memsize_hash.inject(0){|count, (k, v)| count += v}
puts "allocated by memory (#{total_memsize}) (in bytes)"
puts "=============================="
memsize_hash = memsize_hash.sort {|(k1, v1), (k2, v2)| v2 <=> v1 }.first(50)
longest = memsize_hash.first[1].to_s.length
memsize_hash.each do |file_line, memsize|
puts " #{memsize.to_s.rjust(longest)} #{file_line}"
end
total_count = count_hash.inject(0){|count, (k, v)| count += v}
puts ""
puts "object count (#{total_count})"
puts "=============================="
count_hash = count_hash.sort {|(k1, v1), (k2, v2)| v2 <=> v1 }.first(50)
longest = count_hash.first[1].to_s.length
count_hash.each do |file_line, memsize|
puts " #{memsize.to_s.rjust(longest)} #{file_line}"
end
puts ""
puts "High Ref Counts"
puts "=============================="
puts ""
reference_hash = reference_hash.sort {|(k1, v1), (k2, v2)| v2 <=> v1 }.first(50)
longest = count_hash.first[1].to_s.length
reference_hash.each do |file_line, count|
puts " #{count.to_s.rjust(longest)} #{file_line}"
end
if !string_count.empty?
puts ""
puts "Duplicate strings"
puts "=============================="
puts ""
value_count = {}
string_count.each do |string, location_count_hash|
value_count[string] = location_count_hash.values.inject(&:+)
end
value_count = value_count.sort {|(k1, v1), (k2, v2)| v2 <=> v1 }.first(50)
longest = value_count.first[1].to_s.length
value_count.each do |string, c1|
puts " #{c1.to_s.rjust(longest)} #{string.inspect}"
string_count[string].sort {|(k1, v1), (k2, v2)| v2 <=> v1 }.each do |file_line, c2|
puts " #{c2.to_s.rjust(longest)} #{file_line}"
end
puts ""
end
end
end
|