memory_profiler 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 137993daf571e91e9226e91bfac2f5fc8de00e24
4
- data.tar.gz: dd960b34c925167e99d3f99f9e16729210fbd511
3
+ metadata.gz: 5931642a912d8f6a80223dbc83202881a8e35081
4
+ data.tar.gz: 37d78ed2c56c9edf6d7de2d4ef8d5298c22ae402
5
5
  SHA512:
6
- metadata.gz: fe442012610dc38045c586f7a732bfdde5b60471a98196a836d3cd9730f48b5d52ef6f4b6bb493aa4f98de2e64f8773b61093e85355b4d90ae37915dd0c4d8a5
7
- data.tar.gz: 778ff7260499849b6580e6c8a0c4864507af34d7417ad3bcf7c09b9b071ddf2ab45156e6a6c1caf74b61d40d7fd3b81d63013030a53236c9dc7c95d4ede8b7c9
6
+ metadata.gz: c553c559a4e8fca6adbe3a57c0e2b1f2caf4189a101d975b5b458c28fb96ab5710f1cb9c4f19943b92be195ffd993c0039c13ed162448cd19f6a6586f4907b91
7
+ data.tar.gz: c4b1de94478b20c2645d1826c9729b068ec1214ea3b6da83542a67c7ebe484b3acd8d16807d82cdd1ba045658cb4e78ee32b04b12c52cb58c14151d5383021df
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MemoryProfiler
2
2
 
3
- TODO: Write a gem description
3
+ A memory profiler for MRI head
4
4
 
5
5
  ## Installation
6
6
 
@@ -18,7 +18,7 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- TODO: Write usage instructions here
21
+
22
22
 
23
23
  ## Contributing
24
24
 
@@ -27,3 +27,8 @@ TODO: Write usage instructions here
27
27
  3. Commit your changes (`git commit -am 'Add some feature'`)
28
28
  4. Push to the branch (`git push origin my-new-feature`)
29
29
  5. Create new Pull Request
30
+
31
+ ## Changelog
32
+
33
+ - 0.0.3
34
+ - Added string analysis
@@ -27,6 +27,9 @@ module MemoryProfiler
27
27
  allocated = object_list(generation, rvalue_size)
28
28
  end
29
29
 
30
+ results = Results.new
31
+ results.strings_allocated = results.string_report(allocated,top)
32
+
30
33
  GC.enable
31
34
 
32
35
  Helpers.full_gc
@@ -37,11 +40,14 @@ module MemoryProfiler
37
40
  found = allocated[obj.__id__]
38
41
  retained[obj.__id__] = found if found
39
42
  rescue
40
- # __id__ is not defined, skip it
43
+ # __id__ is not defined on BasicObject, skip it
44
+ # we can probably trasplant the object_id at this point,
45
+ # but it is quite rare
41
46
  end
42
47
  end
43
48
 
44
- Results.from_raw(allocated,retained,top)
49
+ results.register_results(allocated,retained,top)
50
+ results
45
51
 
46
52
  end
47
53
 
@@ -32,8 +32,8 @@ module MemoryProfiler
32
32
  "#{stat.file}:#{stat.line}"
33
33
  }
34
34
 
35
- attr_accessor :total_allocated
36
- attr_accessor :total_retained
35
+ attr_accessor :strings_retained, :strings_allocated
36
+ attr_accessor :total_retained, :total_allocated
37
37
 
38
38
  def self.from_raw(allocated, retained, top)
39
39
  self.new.register_results(allocated,retained,top)
@@ -53,13 +53,29 @@ module MemoryProfiler
53
53
  end
54
54
 
55
55
  self.send "#{name}=", result
56
- self.total_allocated = allocated.count
57
- self.total_retained = retained.count
58
56
  end
59
57
 
58
+ self.strings_retained = string_report(retained, top)
59
+
60
+ self.total_allocated = allocated.count
61
+ self.total_retained = retained.count
62
+
60
63
  self
61
64
  end
62
65
 
66
+ StringStat = Struct.new(:string, :count, :location)
67
+
68
+ def string_report(data, top)
69
+ data
70
+ .keep_if{|id,stat| stat.class_name == "String"f}
71
+ .map{|id,stat| [ObjectSpace._id2ref(id), "#{stat.file}:#{stat.line}"]}
72
+ .group_by{|string, location| string}
73
+ .sort_by{|string, list| -list.count}
74
+ .first(top)
75
+ .map{|string,list| [string, list.group_by{|str,location| location}
76
+ .map{|location, locations| [location, locations.count]}]}
77
+ end
78
+
63
79
  def pretty_print(io = STDOUT)
64
80
  io.puts "Total allocated #{total_allocated}"
65
81
  io.puts "Total retained #{total_retained}"
@@ -70,6 +86,25 @@ module MemoryProfiler
70
86
  .each do |(type, metric), name|
71
87
  dump "#{type} #{metric} by #{name}", self.send("#{type}_#{metric}_by_#{name}"), io
72
88
  end
89
+
90
+ io.puts
91
+ dump_strings(io, "Allocated",strings_allocated)
92
+ io.puts
93
+ dump_strings(io, "Retained",strings_retained)
94
+ nil
95
+ end
96
+
97
+ def dump_strings(io, title, strings)
98
+ return unless strings
99
+ io.puts "#{title} String Report"
100
+ io.puts "-----------------------------------"
101
+ strings.each do |string, stats|
102
+ io.puts "#{string[0..200].inspect} x #{stats.reduce(0){|a,b| a + b[1]}}"
103
+ stats.sort_by{|x,y| -y}.each do |location, count|
104
+ io.puts " #{location} x #{count}"
105
+ end
106
+ end
107
+ nil
73
108
  end
74
109
 
75
110
  def dump(description, data, io)
@@ -1,3 +1,3 @@
1
1
  module MemoryProfiler
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: memory_profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-10 00:00:00.000000000 Z
11
+ date: 2013-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -128,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
128
  version: '0'
129
129
  requirements: []
130
130
  rubyforge_project:
131
- rubygems_version: 2.0.7
131
+ rubygems_version: 2.1.3
132
132
  signing_key:
133
133
  specification_version: 4
134
134
  summary: Memory profiling routines for Ruby Head