memory_profiler 0.9.14 → 1.0.1

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
  SHA256:
3
- metadata.gz: 187acbd9601ade1bb6ccdb60bfb4c305ada15097f02278529f8f6a6fc7d68666
4
- data.tar.gz: 33d797db658d4a4507247a0ae9c4b92da568b86e9246f4571a94774b62285c6b
3
+ metadata.gz: e4c8c5a12cd11ab3f9c5ab852e6bca0cb442ccc25f54997f49243a19aa6cef9b
4
+ data.tar.gz: 5c0ca217ca3cbc0edca725071512688443ac24a5d3e9f28980d93d3dd30a323f
5
5
  SHA512:
6
- metadata.gz: 977f958e6b9f3292053ccef51bcef01828cda7d29760f131687d21b00222950fbf1ec4629a7021bfdc4665e137c3f75cfd729a29db60b879a5c30f08da0de097
7
- data.tar.gz: 1cc221f3bf20520a3063031a4d9830e3303d9d9182cafb746aa77d0059888a4a640f2d6dd39a925e31398664018c98e9324565247046310c15ef823419bb6baf
6
+ metadata.gz: 11d3bf57b920c915a0a98f6cea8798349983b0c64047f481ab1227301ff100a8de16f858ee7d21028d32e3dd04015446f77555bfd050755637714da5d1cc08b3
7
+ data.tar.gz: 46d2df335163a6ddc35ea3a0eff97573dc7b8a50d671e9aa8940a5acb300ea342d7eb38e10f03f39f3705c4e9ed318a336c68f72ddf39a5cdf4f6bb81b9cc7e5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.1 - 23-10-2022
4
+
5
+ - Adapts tests to Ruby 3.0 / 3.1
6
+ - Lazy report evaluation
7
+ - Tested under Truffle Ruby
8
+
9
+ ## 1.0.0 - 02-12-2020
10
+
11
+ - Added new CLI `ruby-memory-profiler` which can be used to profile scripts @fatkodima
12
+ - Reduced memory usage when generating reports
13
+ - Some optimizations for Ruby 2.7
14
+ - Remove EOL Rubies: 2.3 and 2.4 are no longer supported (use an earlier version of the gem if needed)
15
+
3
16
  ## 0.9.14 - 28-06-2019
4
17
 
5
18
  - Pass 'normalize_path: true' to pretty_print to have locations stripped
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status](https://travis-ci.org/SamSaffron/memory_profiler.svg?branch=master)](https://travis-ci.org/SamSaffron/memory_profiler)
1
+ [![CI](https://github.com/SamSaffron/memory_profiler/workflows/CI/badge.svg)](https://github.com/SamSaffron/memory_profiler/actions?query=workflow%3ACI)
2
2
  [![Gem Version](https://badge.fury.io/rb/memory_profiler.svg)](https://rubygems.org/gems/memory_profiler)
3
3
 
4
4
  # MemoryProfiler
@@ -7,7 +7,7 @@ A memory profiler for Ruby
7
7
 
8
8
  ## Requirements
9
9
 
10
- Ruby(MRI) Version 2.3.8 and above.
10
+ Ruby(MRI) Version 2.5.0 and above.
11
11
 
12
12
  ## Installation
13
13
 
@@ -25,6 +25,25 @@ Or install it yourself as:
25
25
 
26
26
  ## Usage
27
27
 
28
+ There are two ways to use `memory_profiler`:
29
+ * command line
30
+ * convenience API
31
+
32
+ ### Command Line
33
+
34
+ The easiest way to use memory_profiler is via the command line, which requires no modifications to your program. The basic usage is:
35
+ ```
36
+ $ ruby-memory-profiler [options] <script.rb> [--] [script-options]
37
+ ```
38
+ Where `script.rb` is the program you want to profile.
39
+
40
+ For a full list of options, execute the following command:
41
+ ```
42
+ ruby-memory-profiler -h
43
+ ```
44
+
45
+ ### Convenience API
46
+
28
47
  ```ruby
29
48
  require 'memory_profiler'
30
49
  report = MemoryProfiler.report do
@@ -93,7 +112,7 @@ The `pretty_print` method can take a few options:
93
112
  * `to_file`: a path to your log file - can be given a String
94
113
  * `color_output`: a flag for whether to colorize output - can be given a Boolean
95
114
  * `retained_strings`: how many retained strings to print - can be given an Integer
96
- * `allocated_strings`: how many allocated strings to print - can be given a String
115
+ * `allocated_strings`: how many allocated strings to print - can be given a Integer
97
116
  * `detailed_report`: should report include detailed information - can be given a Boolean
98
117
  * `scale_bytes`: flag to convert byte units (e.g. 183200000 is reported as 183.2 MB, rounds with a precision of 2 decimal digits) - can be given a Boolean
99
118
  * `normalize_paths`: flag to remove a gem's directory path from printed locations - can be given a Boolean
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
5
+
6
+ require "memory_profiler"
7
+
8
+ exit MemoryProfiler::CLI.new.run(ARGV)
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+
5
+ module MemoryProfiler
6
+ class CLI
7
+ BIN_NAME = "ruby-memory-profiler"
8
+ VERSION_INFO = "#{BIN_NAME} #{MemoryProfiler::VERSION}"
9
+
10
+ STATUS_SUCCESS = 0
11
+ STATUS_ERROR = 1
12
+
13
+ DEFAULTS = {
14
+ ignore_files: "memory_profiler/lib"
15
+ }.freeze
16
+
17
+ REPORTER_KEYS = [
18
+ :top, :trace, :ignore_files, :allow_files
19
+ ].freeze
20
+
21
+ RESULTS_KEYS = [
22
+ :to_file, :color_output, :retained_strings, :allocated_strings,
23
+ :detailed_report, :scale_bytes, :normalize_paths
24
+ ].freeze
25
+
26
+ private_constant :BIN_NAME, :VERSION_INFO,:STATUS_SUCCESS, :STATUS_ERROR,
27
+ :DEFAULTS, :REPORTER_KEYS, :RESULTS_KEYS
28
+
29
+ #
30
+
31
+ def run(argv)
32
+ options = {}
33
+ parser = option_parser(options)
34
+ parser.parse!(argv)
35
+
36
+ options = DEFAULTS.merge(options)
37
+
38
+ # Make sure the user specified at least one file
39
+ unless (script = argv.shift)
40
+ puts parser
41
+ puts ""
42
+ puts "#{VERSION_INFO} | ERROR: Must specify a script to run"
43
+ return STATUS_ERROR
44
+ end
45
+
46
+ MemoryProfiler.start(reporter_options(options))
47
+ load script
48
+
49
+ STATUS_SUCCESS
50
+ rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument => e
51
+ puts parser
52
+ puts e.message
53
+ STATUS_ERROR
54
+ ensure
55
+ report = MemoryProfiler.stop
56
+ report&.pretty_print(**results_options(options))
57
+ end
58
+
59
+ private
60
+
61
+ def option_parser(options)
62
+ OptionParser.new do |opts|
63
+ opts.banner = <<~BANNER
64
+
65
+ #{VERSION_INFO}
66
+ A Memory Profiler for Ruby
67
+
68
+ Usage:
69
+ #{BIN_NAME} [options] <script.rb> [--] [script-options]
70
+ BANNER
71
+
72
+ opts.separator ""
73
+ opts.separator "Options:"
74
+
75
+ # Reporter options
76
+ opts.on("-m", "--max=NUM", Integer, "Max number of entries to output. (Defaults to 50)") do |arg|
77
+ options[:top] = arg
78
+ end
79
+
80
+ opts.on("--classes=CLASSES", Array, "A class or list of classes you explicitly want to trace.") do |arg|
81
+ options[:trace] = arg.map { |klass| Object.const_get(klass) }
82
+ end
83
+
84
+ opts.on("--ignore-files=REGEXP", "A regular expression used to exclude certain files from tracing.") do |arg|
85
+ options[:ignore_files] = "#{arg}|memory_profiler/lib"
86
+ end
87
+
88
+ opts.on("--allow-files=FILES", Array, "A string or list of strings to selectively include in tracing.") do |arg|
89
+ options[:allow_files] = arg
90
+ end
91
+
92
+ opts.separator ""
93
+
94
+ # Results options
95
+ opts.on("-o", "--out=FILE", "Write output to a file instead of STDOUT.") do |arg|
96
+ options[:to_file] = arg
97
+ end
98
+
99
+ opts.on("--[no-]color", "Force color output on or off. (Enabled by default)") do |arg|
100
+ options[:color_output] = arg
101
+ end
102
+
103
+ opts.on("--retained-strings=NUM", Integer, "How many retained strings to print.") do |arg|
104
+ options[:retained_strings] = arg
105
+ end
106
+
107
+ opts.on("--allocated-strings=NUM", Integer, "How many allocated strings to print.") do |arg|
108
+ options[:allocated_strings] = arg
109
+ end
110
+
111
+ opts.on("--[no-]detailed", "Print detailed information. (Enabled by default)") do |arg|
112
+ options[:detailed_report] = arg
113
+ end
114
+
115
+ opts.on("--scale-bytes", "Calculates unit prefixes for the numbers of bytes.") do
116
+ options[:scale_bytes] = true
117
+ end
118
+
119
+ opts.on("--normalize-paths", "Print location paths relative to gem's source directory.") do
120
+ options[:normalize_paths] = true
121
+ end
122
+
123
+ opts.on("--pretty", "Easily enable options 'scale-bytes' and 'normalize-paths'") do
124
+ options[:scale_bytes] = options[:normalize_paths] = true
125
+ end
126
+
127
+ opts.separator ""
128
+
129
+ opts.on_tail("-h", "--help", "Show this help message.") do
130
+ puts opts
131
+ exit
132
+ end
133
+
134
+ opts.on_tail("-v", "--version", "Show program version.") do
135
+ puts VERSION_INFO
136
+ exit
137
+ end
138
+ end
139
+ end
140
+
141
+ def reporter_options(options)
142
+ options.select { |k, _v| REPORTER_KEYS.include?(k) }
143
+ end
144
+
145
+ def results_options(options)
146
+ options.select { |k, _v| RESULTS_KEYS.include?(k) }
147
+ end
148
+ end
149
+ end
@@ -16,7 +16,7 @@ module MemoryProfiler
16
16
  gemname
17
17
  elsif /\/rubygems[\.\/]/ =~ path
18
18
  "rubygems"
19
- elsif /ruby\/2\.[^\/]+\/(?<stdlib>[^\/\.]+)/ =~ path
19
+ elsif /ruby\/\d\.[^\/]+\/(?<stdlib>[^\/\.]+)/ =~ path
20
20
  stdlib
21
21
  elsif /(?<app>[^\/]+\/(bin|app|lib))/ =~ path
22
22
  app
@@ -29,8 +29,35 @@ module MemoryProfiler
29
29
  @location_cache[file][line] ||= "#{file}:#{line}"
30
30
  end
31
31
 
32
- def lookup_class_name(klass)
33
- @class_name_cache[klass] ||= ((klass.is_a?(Class) && klass.name) || '<<Unknown>>').to_s
32
+ KERNEL_CLASS_METHOD = Kernel.instance_method(:class)
33
+ if UnboundMethod.method_defined?(:bind_call)
34
+ def object_class(obj)
35
+ klass = obj.class rescue nil
36
+ unless Class === klass
37
+ # attempt to determine the true Class when .class returns something other than a Class
38
+ klass = KERNEL_CLASS_METHOD.bind_call(obj)
39
+ end
40
+ klass
41
+ end
42
+ else
43
+ def object_class(obj)
44
+ klass = obj.class rescue nil
45
+ unless Class === klass
46
+ # attempt to determine the true Class when .class returns something other than a Class
47
+ klass = KERNEL_CLASS_METHOD.bind(obj).call
48
+ end
49
+ klass
50
+ end
51
+ end
52
+
53
+ if Object.name.frozen? # Since Ruby 2.7 Module#name no longer allocate a new string
54
+ def lookup_class_name(klass)
55
+ ((klass.is_a?(Class) && klass.name) || '<<Unknown>>').to_s
56
+ end
57
+ else
58
+ def lookup_class_name(klass)
59
+ @class_name_cache[klass] ||= ((klass.is_a?(Class) && klass.name) || '<<Unknown>>').to_s
60
+ end
34
61
  end
35
62
 
36
63
  def lookup_string(obj)
@@ -5,7 +5,7 @@ module MemoryProfiler
5
5
  class Polychrome
6
6
 
7
7
  def path(text)
8
- gray(text)
8
+ blue(text)
9
9
  end
10
10
 
11
11
  def string(text)
@@ -13,7 +13,7 @@ module MemoryProfiler
13
13
  end
14
14
 
15
15
  def line(text)
16
- gray(text)
16
+ cyan(text)
17
17
  end
18
18
 
19
19
  private
@@ -34,8 +34,7 @@ module MemoryProfiler
34
34
  end
35
35
 
36
36
  def start
37
- GC.start
38
- GC.start
37
+ 3.times { GC.start }
39
38
  GC.start
40
39
  GC.disable
41
40
 
@@ -49,8 +48,11 @@ module MemoryProfiler
49
48
  retained = StatHash.new.compare_by_identity
50
49
 
51
50
  GC.enable
52
- GC.start
53
- GC.start
51
+ # for whatever reason doing GC in a block is more effective at
52
+ # freeing objects.
53
+ # full_mark: true, immediate_mark: true, immediate_sweep: true are already default
54
+ 3.times { GC.start }
55
+ # another start outside of the block to release the block
54
56
  GC.start
55
57
 
56
58
  # Caution: Do not allocate any new Objects between the call to GC.start and the completion of the retained
@@ -86,8 +88,6 @@ module MemoryProfiler
86
88
  # Iterates through objects in memory of a given generation.
87
89
  # Stores results along with meta data of objects collected.
88
90
  def object_list(generation)
89
-
90
- rvalue_size = GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
91
91
  helper = Helpers.new
92
92
 
93
93
  result = StatHash.new.compare_by_identity
@@ -99,11 +99,7 @@ module MemoryProfiler
99
99
  next if @ignore_files && @ignore_files =~ file
100
100
  next if @allow_files && !(@allow_files =~ file)
101
101
 
102
- klass = obj.class rescue nil
103
- unless Class === klass
104
- # attempt to determine the true Class when .class returns something other than a Class
105
- klass = Kernel.instance_method(:class).bind(obj).call
106
- end
102
+ klass = helper.object_class(obj)
107
103
  next if @trace && !trace.include?(klass)
108
104
 
109
105
  begin
@@ -118,7 +114,7 @@ module MemoryProfiler
118
114
  string = klass == String ? helper.lookup_string(obj) : nil
119
115
 
120
116
  # compensate for API bug
121
- memsize = rvalue_size if memsize > 100_000_000_000
117
+ memsize = GC::INTERNAL_CONSTANTS[:RVALUE_SIZE] if memsize > 100_000_000_000
122
118
  result[obj.__id__] = MemoryProfiler::Stat.new(class_name, gem, file, location, memsize, string)
123
119
  rescue
124
120
  # give up if any any error occurs inspecting the object
@@ -24,7 +24,16 @@ module MemoryProfiler
24
24
 
25
25
  TYPES.each do |type|
26
26
  METRICS.each do |metric|
27
- attr_accessor "#{type}_#{metric}_by_#{name}"
27
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
28
+ def #{type}_#{metric}_by_#{name} # def allocated_memory_by_file
29
+ @#{type}_#{metric}_by ||= {} # @allocated_memory_by ||= {}
30
+ #
31
+ @#{type}_#{metric}_by['#{name}'] ||= begin # @allocated_memory_by['file'] ||= begin
32
+ _, stat_attribute = @@lookups.find { |(n, _stat_attribute)| n == '#{name}' } # _, stat_attribute = @@lookups.find { |(n, _stat_attribute)| n == 'file' }
33
+ @#{type}.top_n_#{metric}(@top, stat_attribute) # @allocated.top_n_memory(@top, stat_attribute)
34
+ end # end
35
+ end # end
36
+ RUBY
28
37
  end
29
38
  end
30
39
  end
@@ -34,36 +43,37 @@ module MemoryProfiler
34
43
  register_type 'location', :location
35
44
  register_type 'class', :class_name
36
45
 
37
- attr_accessor :strings_retained, :strings_allocated
46
+ attr_writer :strings_retained, :strings_allocated
38
47
  attr_accessor :total_retained, :total_allocated
39
48
  attr_accessor :total_retained_memsize, :total_allocated_memsize
40
49
 
41
- def register_results(allocated, retained, top)
42
-
43
- @@lookups.each do |name, stat_attribute|
44
-
45
- memsize_results, count_results = allocated.top_n(top, stat_attribute)
46
-
47
- self.send("allocated_memory_by_#{name}=", memsize_results)
48
- self.send("allocated_objects_by_#{name}=", count_results)
49
-
50
- memsize_results, count_results = retained.top_n(top, stat_attribute)
51
-
52
- self.send("retained_memory_by_#{name}=", memsize_results)
53
- self.send("retained_objects_by_#{name}=", count_results)
54
- end
50
+ def initialize
51
+ @allocated = StatHash.new
52
+ @retained = StatHash.new
53
+ @top = 50
54
+ end
55
55
 
56
- self.strings_allocated = string_report(allocated, top)
57
- self.strings_retained = string_report(retained, top)
56
+ def register_results(allocated, retained, top)
57
+ @allocated = allocated
58
+ @retained = retained
59
+ @top = top
58
60
 
59
61
  self.total_allocated = allocated.size
60
- self.total_allocated_memsize = allocated.values.map!(&:memsize).inject(0, :+)
62
+ self.total_allocated_memsize = total_memsize(allocated)
61
63
  self.total_retained = retained.size
62
- self.total_retained_memsize = retained.values.map!(&:memsize).inject(0, :+)
64
+ self.total_retained_memsize = total_memsize(retained)
63
65
 
64
66
  self
65
67
  end
66
68
 
69
+ def strings_allocated
70
+ @strings_allocated ||= string_report(@allocated, @top)
71
+ end
72
+
73
+ def strings_retained
74
+ @strings_retained ||= string_report(@retained, @top)
75
+ end
76
+
67
77
  def scale_bytes(bytes)
68
78
  return "0 B" if bytes.zero?
69
79
 
@@ -73,19 +83,22 @@ module MemoryProfiler
73
83
  end
74
84
 
75
85
  def string_report(data, top)
76
- grouped_strings = data.values
77
- .keep_if { |stat| stat.string_value }
78
- .group_by { |stat| stat.string_value.object_id }
79
- .values
86
+ grouped_strings = Hash.new { |hash, key| hash[key] = [] }
87
+ data.each_value do |stat|
88
+ if stat.string_value
89
+ grouped_strings[stat.string_value.object_id] << stat
90
+ end
91
+ end
92
+
93
+ grouped_strings = grouped_strings.values
80
94
 
81
95
  if grouped_strings.size > top
82
- cutoff = grouped_strings.sort_by!(&:size)[-top].size
83
- grouped_strings.keep_if { |list| list.size >= cutoff }
96
+ grouped_strings.sort_by!(&:size)
97
+ grouped_strings = grouped_strings.drop(grouped_strings.size - top)
84
98
  end
85
99
 
86
100
  grouped_strings
87
101
  .sort! { |a, b| a.size == b.size ? a[0].string_value <=> b[0].string_value : b.size <=> a.size }
88
- .first(top)
89
102
  .map! do |list|
90
103
  # Return array of [string, [[location, count], [location, count], ...]
91
104
  [
@@ -136,10 +149,10 @@ module MemoryProfiler
136
149
  end
137
150
  end
138
151
  end
139
- end
140
152
 
141
- io.puts
142
- print_string_reports(io, options)
153
+ io.puts
154
+ print_string_reports(io, options)
155
+ end
143
156
 
144
157
  io.close if io.is_a? File
145
158
  end
@@ -159,7 +172,7 @@ module MemoryProfiler
159
172
  @normalize_path[path] ||= begin
160
173
  if %r!(/gems/.*)*/gems/(?<gemname>[^/]+)(?<rest>.*)! =~ path
161
174
  "#{gemname}#{rest}"
162
- elsif %r!ruby/2\.[^/]+/(?<stdlib>[^/.]+)(?<rest>.*)! =~ path
175
+ elsif %r!ruby/\d\.[^/]+/(?<stdlib>[^/.]+)(?<rest>.*)! =~ path
163
176
  "ruby/lib/#{stdlib}#{rest}"
164
177
  elsif %r!(?<app>[^/]+/(bin|app|lib))(?<rest>.*)! =~ path
165
178
  "#{app}#{rest}"
@@ -171,6 +184,14 @@ module MemoryProfiler
171
184
 
172
185
  private
173
186
 
187
+ def total_memsize(stat_hash)
188
+ sum = 0
189
+ stat_hash.each_value do |stat|
190
+ sum += stat.memsize
191
+ end
192
+ sum
193
+ end
194
+
174
195
  def print_title(io, title)
175
196
  io.puts
176
197
  io.puts title
@@ -5,27 +5,40 @@ module MemoryProfiler
5
5
  # Fast approach for determining the top_n entries in a Hash of Stat objects.
6
6
  # Returns results for both memory (memsize summed) and objects allocated (count) as a tuple.
7
7
  def top_n(max, metric_method)
8
+ [
9
+ top_n_memory(max, metric_method),
10
+ top_n_objects(max, metric_method)
11
+ ]
12
+ end
13
+
14
+ def top_n_memory(max, metric_method)
15
+ metric_memsize = Hash.new(0)
8
16
 
9
- stat_totals =
10
- self.values
11
- .group_by(&metric_method)
12
- .map do |metric, stats|
13
- [metric, stats.reduce(0) { |sum, stat| sum + stat.memsize }, stats.size]
14
- end
17
+ each_value do |value|
18
+ metric = value.send(metric_method)
19
+ metric_memsize[metric] += value.memsize
20
+ end
21
+
22
+ metric_memsize
23
+ .to_a
24
+ .sort_by! { |metric, memsize| [-memsize, metric] }
25
+ .take(max)
26
+ .map! { |metric, memsize| { data: metric, count: memsize } }
27
+ end
15
28
 
16
- stats_by_memsize =
17
- stat_totals
18
- .sort_by! { |metric, memsize, _count| [-memsize, metric] }
19
- .take(max)
20
- .map! { |metric, memsize, _count| { data: metric, count: memsize } }
29
+ def top_n_objects(max, metric_method)
30
+ metric_objects_count = Hash.new(0)
21
31
 
22
- stats_by_count =
23
- stat_totals
24
- .sort_by! { |metric, _memsize, count| [-count, metric] }
25
- .take(max)
26
- .map! { |metric, _memsize, count| { data: metric, count: count } }
32
+ each_value do |value|
33
+ metric = value.send(metric_method)
34
+ metric_objects_count[metric] += 1
35
+ end
27
36
 
28
- [stats_by_memsize, stats_by_count]
37
+ metric_objects_count
38
+ .to_a
39
+ .sort_by! { |metric, count| [-count, metric] }
40
+ .take(max)
41
+ .map! { |metric, count| { data: metric, count: count } }
29
42
  end
30
43
  end
31
44
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MemoryProfiler
4
- VERSION = "0.9.14"
4
+ VERSION = "1.0.1"
5
5
  end
@@ -9,6 +9,7 @@ require "memory_profiler/stat"
9
9
  require "memory_profiler/stat_hash"
10
10
  require "memory_profiler/results"
11
11
  require "memory_profiler/reporter"
12
+ require "memory_profiler/cli"
12
13
 
13
14
  module MemoryProfiler
14
15
  def self.report(opts = {}, &block)
metadata CHANGED
@@ -1,26 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: memory_profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.14
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-27 00:00:00.000000000 Z
11
+ date: 2022-10-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Memory profiling routines for Ruby 2.3+
13
+ description: Memory profiling routines for Ruby 2.5+
14
14
  email:
15
15
  - sam.saffron@gmail.com
16
- executables: []
16
+ executables:
17
+ - ruby-memory-profiler
17
18
  extensions: []
18
19
  extra_rdoc_files: []
19
20
  files:
20
21
  - CHANGELOG.md
21
22
  - LICENSE.txt
22
23
  - README.md
24
+ - bin/ruby-memory-profiler
23
25
  - lib/memory_profiler.rb
26
+ - lib/memory_profiler/cli.rb
24
27
  - lib/memory_profiler/helpers.rb
25
28
  - lib/memory_profiler/monochrome.rb
26
29
  - lib/memory_profiler/polychrome.rb
@@ -34,7 +37,7 @@ homepage: https://github.com/SamSaffron/memory_profiler
34
37
  licenses:
35
38
  - MIT
36
39
  metadata: {}
37
- post_install_message:
40
+ post_install_message:
38
41
  rdoc_options: []
39
42
  require_paths:
40
43
  - lib
@@ -42,15 +45,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
42
45
  requirements:
43
46
  - - ">="
44
47
  - !ruby/object:Gem::Version
45
- version: 2.3.0
48
+ version: 2.5.0
46
49
  required_rubygems_version: !ruby/object:Gem::Requirement
47
50
  requirements:
48
51
  - - ">="
49
52
  - !ruby/object:Gem::Version
50
53
  version: '0'
51
54
  requirements: []
52
- rubygems_version: 3.0.3
53
- signing_key:
55
+ rubygems_version: 3.3.20
56
+ signing_key:
54
57
  specification_version: 4
55
- summary: Memory profiling routines for Ruby 2.3+
58
+ summary: Memory profiling routines for Ruby 2.5+
56
59
  test_files: []