memory_profiler 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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