heap-profiler 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cd1bb47a992405f240fc5b4cc0da81eab1c834184407fabafa98e466e119d890
4
+ data.tar.gz: b54e6472ed171723cb765002834fc9ef385d977d659aa96bddc5d7f5dff0428d
5
+ SHA512:
6
+ metadata.gz: b052ccea980716b84308ffdfe490916c84cd796dcb40a4329b15d48097955a50ec576f6d440bfc6b143800dd8af2509d82ad675c1f7845ca44850ba6c161a36c
7
+ data.tar.gz: a70adefc9b02b9b22792d94775d982ca6148d45d56ebb47b97ca327e00eabe5ff0fafa663f1eb251a16b143eca6e4f790566c976ada0244f7492646608ab808a
@@ -0,0 +1,59 @@
1
+ name: CI
2
+ on: [push]
3
+
4
+ jobs:
5
+ rubocop:
6
+ name: Rubocop
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - name: Checkout code
10
+ uses: actions/checkout@v2
11
+
12
+ - name: Setup Ruby
13
+ uses: ruby/setup-ruby@v1
14
+ with:
15
+ ruby-version: '2.6'
16
+ - name: Ruby gem cache
17
+ uses: actions/cache@v1
18
+ with:
19
+ path: vendor/bundle
20
+ key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
21
+ restore-keys: |
22
+ ${{ runner.os }}-gems-
23
+ - name: Install gems
24
+ run: |
25
+ bundle config path vendor/bundle
26
+ bundle install --jobs 4 --retry 3
27
+
28
+ - name: Run linters
29
+ run: |
30
+ bin/rubocop -c .rubocop.yml
31
+
32
+ tests:
33
+ runs-on: ubuntu-latest
34
+ strategy:
35
+ matrix:
36
+ ruby: [ '2.6', '2.7' ]
37
+ name: Ruby ${{ matrix.ruby }} Tests
38
+ steps:
39
+ - name: Checkout code
40
+ uses: actions/checkout@v2
41
+
42
+ - name: Setup Ruby
43
+ uses: ruby/setup-ruby@v1
44
+ with:
45
+ ruby-version: ${{ matrix.ruby }}
46
+ - name: Ruby gem cache
47
+ uses: actions/cache@v1
48
+ with:
49
+ path: vendor/bundle
50
+ key: ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles('**/Gemfile.lock') }}
51
+ restore-keys: |
52
+ ${{ runner.os }}-${{ matrix.ruby }}-gems-
53
+ - name: Install gems
54
+ run: |
55
+ bundle config path vendor/bundle
56
+ bundle install --jobs 4 --retry 3
57
+
58
+ - name: Run tests
59
+ run: bundle exec rake
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ .byebug_history
10
+ *.bundle
11
+ *.so
@@ -0,0 +1,20 @@
1
+ inherit_gem:
2
+ rubocop-shopify: rubocop.yml
3
+
4
+ AllCops:
5
+ Exclude:
6
+ - bin/generate-report
7
+ - vendor/bundle/**/*
8
+ - ext/**/*
9
+
10
+ Style/MethodCallWithArgsParentheses:
11
+ Enabled: false
12
+
13
+ Naming/FileName:
14
+ Enabled: false
15
+
16
+ Lint/RescueException:
17
+ Enabled: false
18
+
19
+ Metrics/ParameterLists:
20
+ Enabled: false
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.6.3
6
+ before_install: gem install bundler -v 2.1.4
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ source "https://rubygems.org"
3
+
4
+ # Specify your gem's dependencies in heap-profiler.gemspec
5
+ gemspec
6
+
7
+ gem "rake"
8
+ gem "rake-compiler"
9
+ gem "minitest", "~> 5.0"
10
+ gem "byebug"
11
+ gem "rubocop-shopify", require: false
12
+ gem "benchmark-ips"
@@ -0,0 +1,51 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ heap-profiler (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.1)
10
+ benchmark-ips (2.8.2)
11
+ byebug (11.1.3)
12
+ minitest (5.14.1)
13
+ parallel (1.19.2)
14
+ parser (2.7.1.4)
15
+ ast (~> 2.4.1)
16
+ rainbow (3.0.0)
17
+ rake (13.0.1)
18
+ rake-compiler (1.1.1)
19
+ rake
20
+ regexp_parser (1.7.1)
21
+ rexml (3.2.4)
22
+ rubocop (0.86.0)
23
+ parallel (~> 1.10)
24
+ parser (>= 2.7.0.1)
25
+ rainbow (>= 2.2.2, < 4.0)
26
+ regexp_parser (>= 1.7)
27
+ rexml
28
+ rubocop-ast (>= 0.0.3, < 1.0)
29
+ ruby-progressbar (~> 1.7)
30
+ unicode-display_width (>= 1.4.0, < 2.0)
31
+ rubocop-ast (0.2.0)
32
+ parser (>= 2.7.0.1)
33
+ rubocop-shopify (1.0.4)
34
+ rubocop (>= 0.85, < 0.87)
35
+ ruby-progressbar (1.10.1)
36
+ unicode-display_width (1.7.0)
37
+
38
+ PLATFORMS
39
+ ruby
40
+
41
+ DEPENDENCIES
42
+ benchmark-ips
43
+ byebug
44
+ heap-profiler!
45
+ minitest (~> 5.0)
46
+ rake
47
+ rake-compiler
48
+ rubocop-shopify
49
+
50
+ BUNDLED WITH
51
+ 2.1.4
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Jean Boussier
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,269 @@
1
+ # HeapProfiler
2
+
3
+ A memory profiler for Ruby
4
+
5
+ ## Requirements
6
+
7
+ Ruby(MRI) Version 2.6 and above.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'heap-profiler'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle install
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install heap-profiler
24
+
25
+ ## Usage
26
+
27
+ ### Profiling Mode
28
+
29
+ HeapProfiler can be used to measure memory allocations and retentions of a Ruby code snippet.
30
+
31
+ To record a profile:
32
+
33
+ ```ruby
34
+ require 'heap-profiler'
35
+ HeapProfiler.report('path/to/report/directory') do
36
+ # You code here
37
+ end
38
+ ```
39
+
40
+ To then analyse the profile, run the `heap-profiler` command against the directory you specified.
41
+ Note that on large applications this can take a while, but if you are profiling a production
42
+ application, you can download the profile directory and do the analysis on another machine.
43
+
44
+ ```bash
45
+ $ heap-profiler path/to/report/directory
46
+ Total allocated: 3.64 kB (35 objects)
47
+ Total retained: 728.00 B (11 objects)
48
+
49
+ allocated memory by gem
50
+ -----------------------------------
51
+ 3.64 kB other
52
+
53
+ allocated memory by file
54
+ -----------------------------------
55
+ 3.64 kB bin/generate-report
56
+
57
+ allocated memory by location
58
+ -----------------------------------
59
+ 3.17 kB bin/generate-report:32
60
+ 157.00 B bin/generate-report:26
61
+ 72.00 B bin/generate-report:20
62
+ 40.00 B bin/generate-report:29
63
+ 40.00 B bin/generate-report:28
64
+ 40.00 B bin/generate-report:24
65
+ 40.00 B bin/generate-report:23
66
+ 40.00 B bin/generate-report:22
67
+ 40.00 B bin/generate-report:21
68
+
69
+ allocated memory by class
70
+ -----------------------------------
71
+ 1.18 kB Class
72
+ 848.00 B <iseq> (IMEMO)
73
+ 597.00 B String
74
+ 384.00 B <ment> (IMEMO)
75
+ 192.00 B Hash
76
+ 192.00 B Array
77
+ 80.00 B <ifunc> (IMEMO)
78
+ 80.00 B <cref> (IMEMO)
79
+ 40.00 B Symbol
80
+ 40.00 B SomeCustomStuff
81
+
82
+ allocated objects by gem
83
+ -----------------------------------
84
+ 35 other
85
+
86
+ allocated objects by file
87
+ -----------------------------------
88
+ 35 bin/generate-report
89
+
90
+ allocated objects by location
91
+ -----------------------------------
92
+ 27 bin/generate-report:32
93
+ 1 bin/generate-report:29
94
+ 1 bin/generate-report:28
95
+ 1 bin/generate-report:26
96
+ 1 bin/generate-report:24
97
+ 1 bin/generate-report:23
98
+ 1 bin/generate-report:22
99
+ 1 bin/generate-report:21
100
+ 1 bin/generate-report:20
101
+
102
+ allocated objects by class
103
+ -----------------------------------
104
+ 12 String
105
+ 8 <ment> (IMEMO)
106
+ 4 Array
107
+ 2 Class
108
+ 2 <iseq> (IMEMO)
109
+ 2 <ifunc> (IMEMO)
110
+ 2 <cref> (IMEMO)
111
+ 1 Symbol
112
+ 1 SomeCustomStuff
113
+ 1 Hash
114
+
115
+ retained memory by gem
116
+ -----------------------------------
117
+ 728.00 B other
118
+
119
+ retained memory by file
120
+ -----------------------------------
121
+ 728.00 B bin/generate-report
122
+
123
+ retained memory by location
124
+ -----------------------------------
125
+ 168.00 B bin/generate-report:28
126
+ 168.00 B bin/generate-report:26
127
+ 160.00 B bin/generate-report:32
128
+ 72.00 B bin/generate-report:20
129
+ 40.00 B bin/generate-report:24
130
+ 40.00 B bin/generate-report:23
131
+ 40.00 B bin/generate-report:22
132
+ 40.00 B bin/generate-report:21
133
+
134
+ retained memory by class
135
+ -----------------------------------
136
+ 336.00 B Hash
137
+ 240.00 B String
138
+ 72.00 B Array
139
+ 40.00 B Symbol
140
+ 40.00 B SomeCustomStuff
141
+
142
+ retained objects by gem
143
+ -----------------------------------
144
+ 11 other
145
+
146
+ retained objects by file
147
+ -----------------------------------
148
+ 11 bin/generate-report
149
+
150
+ retained objects by location
151
+ -----------------------------------
152
+ 4 bin/generate-report:32
153
+ 1 bin/generate-report:28
154
+ 1 bin/generate-report:26
155
+ 1 bin/generate-report:24
156
+ 1 bin/generate-report:23
157
+ 1 bin/generate-report:22
158
+ 1 bin/generate-report:21
159
+ 1 bin/generate-report:20
160
+
161
+ retained objects by class
162
+ -----------------------------------
163
+ 6 String
164
+ 2 Hash
165
+ 1 Symbol
166
+ 1 SomeCustomStuff
167
+ 1 Array
168
+
169
+ Allocated String Report
170
+ -----------------------------------
171
+ 80.00 B 2 "foo="
172
+ 2 bin/generate-report:32
173
+
174
+ 80.00 B 2 "foo"
175
+ 2 bin/generate-report:32
176
+
177
+ 80.00 B 2 "bar="
178
+ 2 bin/generate-report:32
179
+
180
+ 80.00 B 2 "I am retained"
181
+ 1 bin/generate-report:22
182
+ 1 bin/generate-report:21
183
+
184
+ 40.00 B 1 "I am retained too"
185
+ 1 bin/generate-report:23
186
+
187
+ 40.00 B 1 "I am allocated too"
188
+ 1 bin/generate-report:29
189
+
190
+ 40.00 B 1 "I am allocated"
191
+ 1 bin/generate-report:28
192
+
193
+ 157.00 B 1 "I am a very very long string I am a very very long string I am a very very long string I am a very very long string "
194
+ 1 bin/generate-report:26
195
+
196
+
197
+ Retained String Report
198
+ -----------------------------------
199
+ 80.00 B 2 "I am retained"
200
+ 1 bin/generate-report:22
201
+ 1 bin/generate-report:21
202
+
203
+ 40.00 B 1 "foo="
204
+ 1 bin/generate-report:32
205
+
206
+ 40.00 B 1 "foo"
207
+ 1 bin/generate-report:32
208
+
209
+ 40.00 B 1 "bar="
210
+ 1 bin/generate-report:32
211
+
212
+ 40.00 B 1 "I am retained too"
213
+ 1 bin/generate-report:23
214
+ ```
215
+
216
+ ### Heap Analysis
217
+
218
+ Alternatively if you with to analyse the entire heap of your Ruby process.
219
+
220
+ If you can, you should enable allocation tracing as early as possible during your application boot process, e.g. in `config/boot.rb` for Rails apps.
221
+
222
+ ```ruby
223
+ require 'objspace'
224
+ ObjectSpace.trace_object_allocations_start.
225
+ ```
226
+
227
+ Then to dump the heap:
228
+
229
+ ```ruby
230
+ require 'objspace'
231
+ ObjectSpace.dump_all(output: File.open('path/to/file.heap', 'w+'))
232
+ ```
233
+
234
+ Then run `heap-profiler` against it:
235
+
236
+ ```bash
237
+ heap-profiler path/to/file.heap
238
+ ```
239
+
240
+ ## How is it different from memory_profiler?
241
+
242
+ `heap-profiler` is heavilly inspired of `memory_profiler`, it aims at being as similar as possible.
243
+ However it uses a different Ruby API to gather data.
244
+
245
+ `memory_profiler` uses [`ObjectSpace.each_object`](https://ruby-doc.org/core-2.7.1/ObjectSpace.html#method-c-each_object) which contrary to what its name
246
+ suggest doesn't expose all existing object. There are many objects that the Ruby VM consider "internal" (see MRI's `internal_object_p(VALUE)`) and won't yield to `each_object`.
247
+
248
+ On the other hand `heap-profiler` uses [`ObjectSpace.dump_all`](https://ruby-doc.org/stdlib-2.7.1/libdoc/objspace/rdoc/ObjectSpace.html#method-c-dump_all), which
249
+ does serialize every objects, including internal ones, into JSON files. This leads to more exhaustive reports.
250
+
251
+ ## Development
252
+
253
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
254
+
255
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
256
+
257
+ ## Contributing
258
+
259
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/heap-profiler.
260
+
261
+ ## Thanks
262
+
263
+ This gem was heavilly inspired from http://github.com/SamSaffron/memory_profiler, it even borrowed some code from it, so thanks to [@SamSaffron](https://github.com/SamSaffron).
264
+
265
+ It also makes heavy use of https://github.com/simdjson/simdjson for fast heap dump parsing. So big thanks to [Daniel Lemire](https://github.com/lemire) and [John Keiser](https://github.com/jkeiser).
266
+
267
+ ## License
268
+
269
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).