memory_profiler 0.9.12 → 0.9.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/LICENSE.txt +1 -1
- data/README.md +21 -6
- data/lib/memory_profiler.rb +2 -0
- data/lib/memory_profiler/helpers.rb +4 -2
- data/lib/memory_profiler/monochrome.rb +2 -0
- data/lib/memory_profiler/polychrome.rb +2 -0
- data/lib/memory_profiler/reporter.rb +4 -3
- data/lib/memory_profiler/results.rb +37 -5
- data/lib/memory_profiler/stat.rb +2 -0
- data/lib/memory_profiler/stat_hash.rb +2 -0
- data/lib/memory_profiler/top_n.rb +2 -0
- data/lib/memory_profiler/version.rb +3 -1
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df0b1ccbb40909e048bc0064c0f340997ab72629274a71704885c0d1988eb14c
|
4
|
+
data.tar.gz: 73181a0702537823a3f040c1dbe64a8a432ef945fdc761d923b094c8194a57ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db95ae6758da369bba200ccc7da4af2c01115f9c2d55d607a5e2e0bf135825a65acb0b44393870bdc0cc8fb4e1d0310533e40560721ab9a22856f175f661d58f
|
7
|
+
data.tar.gz: e6e9ca6e80929277f9d937c516d6582d206360b086e38ccd15ce7fe2d4a9be14c684749f665a8151affd54bcc107068493a815bc0d4f60caa4660a473954717e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.9.13 - 22-03-2019
|
4
|
+
|
5
|
+
- remove support explicitly for all EOL rubies, 2.1 and 2.2
|
6
|
+
- frozen string literal comment @RST-J
|
7
|
+
- scale_bytes option @RST-J
|
8
|
+
|
3
9
|
## 0.9.12
|
4
10
|
- Correct bug under-reporting memory for large string allocation @sam
|
5
11
|
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
|
4
4
|
# MemoryProfiler
|
5
5
|
|
6
|
-
A memory profiler for Ruby
|
6
|
+
A memory profiler for Ruby
|
7
7
|
|
8
|
-
## Requirements
|
8
|
+
## Requirements
|
9
9
|
|
10
|
-
Ruby(MRI) Version 2.
|
10
|
+
Ruby(MRI) Version 2.3.8 and above.
|
11
11
|
|
12
12
|
## Installation
|
13
13
|
|
@@ -52,7 +52,9 @@ be the only time you can retrieve the report using this API.
|
|
52
52
|
|
53
53
|
## Options
|
54
54
|
|
55
|
-
|
55
|
+
### `report`
|
56
|
+
|
57
|
+
The `report` method can take a few options:
|
56
58
|
|
57
59
|
* `top`: maximum number of entries to display in a report (default is 50)
|
58
60
|
* `allow_files`: include only certain files from tracing - can be given as a String, Regexp, or array of Strings
|
@@ -84,7 +86,20 @@ allocated memory by file
|
|
84
86
|
. . .
|
85
87
|
```
|
86
88
|
|
87
|
-
|
89
|
+
### `pretty_print`
|
90
|
+
|
91
|
+
The `pretty_print` method can take a few options:
|
92
|
+
|
93
|
+
* `to_file`: a path to your log file - can be given a String
|
94
|
+
* `color_output`: a flag for whether to colorize output - can be given a Boolean
|
95
|
+
* `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
|
97
|
+
* `detailed_report`: should report include detailed information - can be given a Boolean
|
98
|
+
* `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
|
+
|
100
|
+
Check out `Results#pretty_print` for more details.
|
101
|
+
|
102
|
+
For example to report to file, use `pretty_print` method with `to_file` option and `path_to_your_log_file` string:
|
88
103
|
```
|
89
104
|
$ pry
|
90
105
|
pry> require 'memory_profiler'
|
@@ -364,7 +379,7 @@ The report breaks down 2 key concepts.
|
|
364
379
|
|
365
380
|
**Allocated**: All object allocation and memory allocation during code block.
|
366
381
|
|
367
|
-
As a general rule "retained" will always be smaller than or equal to allocated.
|
382
|
+
As a general rule "retained" will always be smaller than or equal to allocated.
|
368
383
|
|
369
384
|
Memory profiler will tell you aggregate costs of the above, for example requiring the mime-types gem above results in approx 2MB of retained memory in 22K or so objects. The actual RSS cost will always be slightly higher as MRI heaps are not squashed to size and memory fragments. In future we may be able to calculate a rough long term GC cost of retained objects (for major GCs).
|
370
385
|
|
data/lib/memory_profiler.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MemoryProfiler
|
2
4
|
class Helpers
|
3
5
|
|
@@ -13,13 +15,13 @@ module MemoryProfiler
|
|
13
15
|
if /(\/gems\/.*)*\/gems\/(?<gemname>[^\/]+)/ =~ path
|
14
16
|
gemname
|
15
17
|
elsif /\/rubygems[\.\/]/ =~ path
|
16
|
-
"rubygems"
|
18
|
+
"rubygems"
|
17
19
|
elsif /ruby\/2\.[^\/]+\/(?<stdlib>[^\/\.]+)/ =~ path
|
18
20
|
stdlib
|
19
21
|
elsif /(?<app>[^\/]+\/(bin|app|lib))/ =~ path
|
20
22
|
app
|
21
23
|
else
|
22
|
-
"other"
|
24
|
+
"other"
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'objspace'
|
2
4
|
module MemoryProfiler
|
3
5
|
# Reporter is the top level API used for generating memory reports.
|
@@ -86,7 +88,6 @@ module MemoryProfiler
|
|
86
88
|
def object_list(generation)
|
87
89
|
|
88
90
|
rvalue_size = GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
|
89
|
-
rvalue_size_adjustment = RUBY_VERSION < '2.2' ? rvalue_size : 0
|
90
91
|
helper = Helpers.new
|
91
92
|
|
92
93
|
result = StatHash.new.compare_by_identity
|
@@ -94,7 +95,7 @@ module MemoryProfiler
|
|
94
95
|
ObjectSpace.each_object do |obj|
|
95
96
|
next unless ObjectSpace.allocation_generation(obj) == generation
|
96
97
|
|
97
|
-
file = ObjectSpace.allocation_sourcefile(obj) || "(no name)"
|
98
|
+
file = ObjectSpace.allocation_sourcefile(obj) || "(no name)"
|
98
99
|
next if @ignore_files && @ignore_files =~ file
|
99
100
|
next if @allow_files && !(@allow_files =~ file)
|
100
101
|
|
@@ -113,7 +114,7 @@ module MemoryProfiler
|
|
113
114
|
|
114
115
|
# we do memsize first to avoid freezing as a side effect and shifting
|
115
116
|
# storage to the new frozen string, this happens on @hash[s] in lookup_string
|
116
|
-
memsize = ObjectSpace.memsize_of(obj)
|
117
|
+
memsize = ObjectSpace.memsize_of(obj)
|
117
118
|
string = klass == String ? helper.lookup_string(obj) : nil
|
118
119
|
|
119
120
|
# compensate for API bug
|
@@ -1,5 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MemoryProfiler
|
2
4
|
class Results
|
5
|
+
UNIT_PREFIXES = {
|
6
|
+
0 => 'B',
|
7
|
+
3 => 'kB',
|
8
|
+
6 => 'MB',
|
9
|
+
9 => 'GB',
|
10
|
+
12 => 'TB',
|
11
|
+
15 => 'PB',
|
12
|
+
18 => 'EB',
|
13
|
+
21 => 'ZB',
|
14
|
+
24 => 'YB'
|
15
|
+
}.freeze
|
3
16
|
|
4
17
|
def self.register_type(name, stat_attribute)
|
5
18
|
@@lookups ||= []
|
@@ -46,6 +59,14 @@ module MemoryProfiler
|
|
46
59
|
self
|
47
60
|
end
|
48
61
|
|
62
|
+
def scale_bytes(bytes)
|
63
|
+
return "0 B" if bytes.zero?
|
64
|
+
|
65
|
+
scale = Math.log10(bytes).div(3) * 3
|
66
|
+
scale = 24 if scale > 24
|
67
|
+
"#{(bytes / 10.0**scale).round(2)} #{UNIT_PREFIXES[scale]}"
|
68
|
+
end
|
69
|
+
|
49
70
|
def string_report(data, top)
|
50
71
|
grouped_strings = data.values.
|
51
72
|
keep_if { |stat| stat.string_value }.
|
@@ -76,6 +97,7 @@ module MemoryProfiler
|
|
76
97
|
# @option opts [Integer] :retained_strings how many retained strings to print
|
77
98
|
# @option opts [Integer] :allocated_strings how many allocated strings to print
|
78
99
|
# @option opts [Boolean] :detailed_report should report include detailed information
|
100
|
+
# @option opts [Boolean] :scale_bytes calculates unit prefixes for the numbers of bytes
|
79
101
|
def pretty_print(io = $stdout, **options)
|
80
102
|
# Handle the special case that Ruby PrettyPrint expects `pretty_print`
|
81
103
|
# to be a customized pretty printing function for a class
|
@@ -86,8 +108,16 @@ module MemoryProfiler
|
|
86
108
|
color_output = options.fetch(:color_output) { io.respond_to?(:isatty) && io.isatty }
|
87
109
|
@colorize = color_output ? Polychrome.new : Monochrome.new
|
88
110
|
|
89
|
-
|
90
|
-
|
111
|
+
if options[:scale_bytes]
|
112
|
+
total_allocated_output = scale_bytes(total_allocated_memsize)
|
113
|
+
total_retained_output = scale_bytes(total_retained_memsize)
|
114
|
+
else
|
115
|
+
total_allocated_output = "#{total_allocated_memsize} bytes"
|
116
|
+
total_retained_output = "#{total_retained_memsize} bytes"
|
117
|
+
end
|
118
|
+
|
119
|
+
io.puts "Total allocated: #{total_allocated_output} (#{total_allocated} objects)"
|
120
|
+
io.puts "Total retained: #{total_retained_output} (#{total_retained} objects)"
|
91
121
|
|
92
122
|
if options[:detailed_report] != false
|
93
123
|
io.puts
|
@@ -95,7 +125,8 @@ module MemoryProfiler
|
|
95
125
|
.product(["memory", "objects"])
|
96
126
|
.product(["gem", "file", "location", "class"])
|
97
127
|
.each do |(type, metric), name|
|
98
|
-
|
128
|
+
scale_data = metric == "memory" && options[:scale_bytes]
|
129
|
+
dump "#{type} #{metric} by #{name}", self.send("#{type}_#{metric}_by_#{name}"), io, scale_data
|
99
130
|
end
|
100
131
|
end
|
101
132
|
|
@@ -129,12 +160,13 @@ module MemoryProfiler
|
|
129
160
|
nil
|
130
161
|
end
|
131
162
|
|
132
|
-
def dump(description, data, io)
|
163
|
+
def dump(description, data, io, scale_data)
|
133
164
|
io.puts description
|
134
165
|
io.puts @colorize.line("-----------------------------------")
|
135
166
|
if data && !data.empty?
|
136
167
|
data.each do |item|
|
137
|
-
|
168
|
+
data_string = scale_data ? scale_bytes(item[:count]) : item[:count].to_s
|
169
|
+
io.puts "#{data_string.rjust(10)} #{item[:data]}"
|
138
170
|
end
|
139
171
|
else
|
140
172
|
io.puts "NO DATA"
|
data/lib/memory_profiler/stat.rb
CHANGED
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memory_profiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: Memory profiling routines for Ruby 2.
|
13
|
+
description: Memory profiling routines for Ruby 2.3+
|
14
14
|
email:
|
15
15
|
- sam.saffron@gmail.com
|
16
16
|
executables: []
|
@@ -42,16 +42,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
42
|
requirements:
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 2.
|
45
|
+
version: 2.3.0
|
46
46
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
48
|
- - ">="
|
49
49
|
- !ruby/object:Gem::Version
|
50
50
|
version: '0'
|
51
51
|
requirements: []
|
52
|
-
|
53
|
-
rubygems_version: 2.7.6
|
52
|
+
rubygems_version: 3.0.3
|
54
53
|
signing_key:
|
55
54
|
specification_version: 4
|
56
|
-
summary: Memory profiling routines for Ruby 2.
|
55
|
+
summary: Memory profiling routines for Ruby 2.3+
|
57
56
|
test_files: []
|