heap-profiler 0.8.0.rc1-aarch64-linux

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/cibuildgem.yaml +87 -0
  3. data/.github/workflows/tests.yml +33 -0
  4. data/.gitignore +11 -0
  5. data/.rubocop.yml +29 -0
  6. data/.ruby-version +1 -0
  7. data/Gemfile +13 -0
  8. data/Gemfile.lock +69 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +291 -0
  11. data/Rakefile +17 -0
  12. data/TODO.md +3 -0
  13. data/benchmark/address-parsing.rb +15 -0
  14. data/benchmark/indexing.rb +17 -0
  15. data/bin/console +15 -0
  16. data/bin/generate-report +49 -0
  17. data/bin/rubocop +29 -0
  18. data/bin/setup +8 -0
  19. data/bin/testunit +9 -0
  20. data/dev.yml +20 -0
  21. data/exe/heap-profiler +5 -0
  22. data/ext/heap_profiler/extconf.rb +9 -0
  23. data/ext/heap_profiler/heap_profiler.cpp +335 -0
  24. data/ext/heap_profiler/simdjson.cpp +15047 -0
  25. data/ext/heap_profiler/simdjson.h +32071 -0
  26. data/heap-profiler.gemspec +31 -0
  27. data/lib/heap-profiler.rb +6 -0
  28. data/lib/heap_profiler/3.1/heap_profiler.so +0 -0
  29. data/lib/heap_profiler/3.2/heap_profiler.so +0 -0
  30. data/lib/heap_profiler/3.3/heap_profiler.so +0 -0
  31. data/lib/heap_profiler/3.4/heap_profiler.so +0 -0
  32. data/lib/heap_profiler/4.0/heap_profiler.so +0 -0
  33. data/lib/heap_profiler/analyzer.rb +232 -0
  34. data/lib/heap_profiler/cli.rb +140 -0
  35. data/lib/heap_profiler/diff.rb +39 -0
  36. data/lib/heap_profiler/dump.rb +97 -0
  37. data/lib/heap_profiler/full.rb +12 -0
  38. data/lib/heap_profiler/index.rb +89 -0
  39. data/lib/heap_profiler/monochrome.rb +19 -0
  40. data/lib/heap_profiler/parser.rb +83 -0
  41. data/lib/heap_profiler/polychrome.rb +93 -0
  42. data/lib/heap_profiler/reporter.rb +118 -0
  43. data/lib/heap_profiler/results.rb +256 -0
  44. data/lib/heap_profiler/runtime.rb +30 -0
  45. data/lib/heap_profiler/version.rb +4 -0
  46. metadata +94 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0f7eb31510a696d4b47aebb1d8c543f0d0af9c2d24d8a34f295e0d2accd021b2
4
+ data.tar.gz: c08cedbf4cf1f7d95911e2abe33dbc0870993b059625026cfa76693aff37dc29
5
+ SHA512:
6
+ metadata.gz: 2af40908af944e1946ba8eff969e3a4cb3f0785df04bf366d951f5b99d89c461638a7b426c49b370c71538dcd8f29ac57a9c1f55de2f71d071a8a93834f8b13a
7
+ data.tar.gz: 0315f07e4c408de39e7184a3891856005782a7f76a1ba24f211a9c03bf23c6d7e15ce7b0e0b2607d891c32d0880497fa9a7dac313d656ac0cd5e3eadafdd390a
@@ -0,0 +1,87 @@
1
+ name: "Package and release gems with precompiled binaries"
2
+ on:
3
+ workflow_dispatch:
4
+ inputs:
5
+ release:
6
+ description: "If the whole build passes on all platforms, release the gems on RubyGems.org"
7
+ required: false
8
+ type: boolean
9
+ default: false
10
+ jobs:
11
+ compile:
12
+ timeout-minutes: 20
13
+ name: "Cross compile the gem on different ruby versions"
14
+ strategy:
15
+ matrix:
16
+ os: ["macos-latest", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-15-intel"]
17
+ runs-on: "${{ matrix.os }}"
18
+ steps:
19
+ - name: "Checkout code"
20
+ uses: "actions/checkout@v5"
21
+ - name: "Setup Ruby"
22
+ uses: "ruby/setup-ruby@v1"
23
+ with:
24
+ ruby-version: "3.1.7"
25
+ bundler-cache: true
26
+ - name: "Run cibuildgem"
27
+ uses: "shopify/cibuildgem/.github/actions/cibuildgem@main"
28
+ with:
29
+ step: "compile"
30
+ test:
31
+ timeout-minutes: 20
32
+ name: "Run the test suite"
33
+ needs: compile
34
+ strategy:
35
+ matrix:
36
+ os: ["macos-latest", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-15-intel"]
37
+ rubies: ["3.1", "3.2", "3.3", "3.4", "4.0"]
38
+ type: ["cross", "native"]
39
+ runs-on: "${{ matrix.os }}"
40
+ steps:
41
+ - name: "Checkout code"
42
+ uses: "actions/checkout@v5"
43
+ - name: "Setup Ruby"
44
+ uses: "ruby/setup-ruby@v1"
45
+ with:
46
+ ruby-version: "${{ matrix.rubies }}"
47
+ bundler-cache: true
48
+ - name: "Run cibuildgem"
49
+ uses: "shopify/cibuildgem/.github/actions/cibuildgem@main"
50
+ with:
51
+ step: "test_${{ matrix.type }}"
52
+ install:
53
+ timeout-minutes: 5
54
+ name: "Verify the gem can be installed"
55
+ needs: test
56
+ strategy:
57
+ matrix:
58
+ os: ["macos-latest", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-15-intel"]
59
+ runs-on: "${{ matrix.os }}"
60
+ steps:
61
+ - name: "Setup Ruby"
62
+ uses: "ruby/setup-ruby@v1"
63
+ with:
64
+ ruby-version: "4.0"
65
+ - name: "Run cibuildgem"
66
+ uses: "shopify/cibuildgem/.github/actions/cibuildgem@main"
67
+ with:
68
+ step: "install"
69
+ release:
70
+ environment: release
71
+ permissions:
72
+ id-token: write
73
+ contents: read
74
+ timeout-minutes: 5
75
+ if: ${{ inputs.release }}
76
+ name: "Release all gems with RubyGems"
77
+ needs: install
78
+ runs-on: "ubuntu-latest"
79
+ steps:
80
+ - name: "Setup Ruby"
81
+ uses: "ruby/setup-ruby@v1"
82
+ with:
83
+ ruby-version: "4.0"
84
+ - name: "Run cibuildgem"
85
+ uses: "shopify/cibuildgem/.github/actions/cibuildgem@main"
86
+ with:
87
+ step: "release"
@@ -0,0 +1,33 @@
1
+ name: CI
2
+ on: [push]
3
+
4
+ jobs:
5
+ rubocop:
6
+ name: Rubocop
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v3
10
+ - name: Set up Ruby
11
+ uses: ruby/setup-ruby@v1
12
+ with:
13
+ ruby-version: '3.4'
14
+ bundler-cache: true
15
+ - name: Run linters
16
+ run: |
17
+ bin/rubocop -c .rubocop.yml
18
+
19
+ tests:
20
+ runs-on: ubuntu-latest
21
+ strategy:
22
+ matrix:
23
+ ruby: [ '3.1', '3.2', '3.3', '3.4', '4.0' ]
24
+ name: Ruby ${{ matrix.ruby }} Tests
25
+ steps:
26
+ - uses: actions/checkout@v3
27
+ - name: Set up Ruby
28
+ uses: ruby/setup-ruby@v1
29
+ with:
30
+ ruby-version: ${{ matrix.ruby }}
31
+ bundler-cache: true
32
+ - name: Run tests
33
+ run: bundle exec rake
data/.gitignore ADDED
@@ -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
data/.rubocop.yml ADDED
@@ -0,0 +1,29 @@
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
+ Style/RedundantBegin:
14
+ Enabled: false
15
+
16
+ Naming/FileName:
17
+ Enabled: false
18
+
19
+ Lint/RescueException:
20
+ Enabled: false
21
+
22
+ Lint/MissingSuper:
23
+ Enabled: false
24
+
25
+ Lint/AssignmentInCondition:
26
+ Enabled: false
27
+
28
+ Metrics/ParameterLists:
29
+ Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.3.1
data/Gemfile ADDED
@@ -0,0 +1,13 @@
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"
13
+ gem "stackprof"
data/Gemfile.lock ADDED
@@ -0,0 +1,69 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ heap-profiler (0.8.0.rc1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.3)
10
+ benchmark-ips (2.14.0)
11
+ byebug (12.0.0)
12
+ json (2.17.1)
13
+ language_server-protocol (3.17.0.5)
14
+ lint_roller (1.1.0)
15
+ minitest (5.26.2)
16
+ parallel (1.27.0)
17
+ parser (3.3.10.0)
18
+ ast (~> 2.4.1)
19
+ racc
20
+ prism (1.6.0)
21
+ racc (1.8.1)
22
+ rainbow (3.1.1)
23
+ rake (13.3.1)
24
+ rake-compiler (1.3.0)
25
+ rake
26
+ regexp_parser (2.11.3)
27
+ rubocop (1.81.7)
28
+ json (~> 2.3)
29
+ language_server-protocol (~> 3.17.0.2)
30
+ lint_roller (~> 1.1.0)
31
+ parallel (~> 1.10)
32
+ parser (>= 3.3.0.2)
33
+ rainbow (>= 2.2.2, < 4.0)
34
+ regexp_parser (>= 2.9.3, < 3.0)
35
+ rubocop-ast (>= 1.47.1, < 2.0)
36
+ ruby-progressbar (~> 1.7)
37
+ unicode-display_width (>= 2.4.0, < 4.0)
38
+ rubocop-ast (1.48.0)
39
+ parser (>= 3.3.7.2)
40
+ prism (~> 1.4)
41
+ rubocop-shopify (1.0.7)
42
+ rubocop (~> 1.4)
43
+ ruby-progressbar (1.13.0)
44
+ stackprof (0.2.27)
45
+ unicode-display_width (3.2.0)
46
+ unicode-emoji (~> 4.1)
47
+ unicode-emoji (4.2.0)
48
+
49
+ PLATFORMS
50
+ aarch64-linux
51
+ arm64-darwin-23
52
+ arm64-darwin-25
53
+ x86_64-darwin-20
54
+ x86_64-darwin-22
55
+ x86_64-darwin-24
56
+ x86_64-linux
57
+
58
+ DEPENDENCIES
59
+ benchmark-ips
60
+ byebug
61
+ heap-profiler!
62
+ minitest (~> 5.0)
63
+ rake
64
+ rake-compiler
65
+ rubocop-shopify
66
+ stackprof
67
+
68
+ BUNDLED WITH
69
+ 2.5.10
data/LICENSE.txt ADDED
@@ -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.
data/README.md ADDED
@@ -0,0 +1,291 @@
1
+ # HeapProfiler
2
+
3
+ A memory profiler for Ruby
4
+
5
+ ## Requirements
6
+
7
+ Ruby(MRI) Version 2.5 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
+ ### Options
45
+
46
+ ```
47
+ Usage: heap-profiler <directory_or_heap_dump> OPTIONS
48
+
49
+ OPTIONS
50
+
51
+ -r, --retained-only Only compute report for memory retentions.
52
+ -m, --max=NUM Max number of entries to output. (Defaults to 50)
53
+ --batch-size SIZE Sets the simdjson parser batch size. It must be larger than the largest JSON document in the heap dump, and defaults to 10MB.
54
+ ```
55
+
56
+
57
+
58
+ ```bash
59
+ $ heap-profiler path/to/report/directory
60
+ Total allocated: 3.72 kB (36 objects)
61
+ Total retained: 808.00 B (12 objects)
62
+
63
+ allocated memory by gem
64
+ -----------------------------------
65
+ 3.72 kB other
66
+
67
+ allocated memory by file
68
+ -----------------------------------
69
+ 3.72 kB bin/generate-report
70
+
71
+ allocated memory by location
72
+ -----------------------------------
73
+ 3.17 kB bin/generate-report:34
74
+ 157.00 B bin/generate-report:28
75
+ 80.00 B bin/generate-report:21
76
+ 72.00 B bin/generate-report:26
77
+ 40.00 B bin/generate-report:31
78
+ 40.00 B bin/generate-report:30
79
+ 40.00 B bin/generate-report:25
80
+ 40.00 B bin/generate-report:24
81
+ 40.00 B bin/generate-report:23
82
+ 40.00 B bin/generate-report:22
83
+
84
+ allocated memory by class
85
+ -----------------------------------
86
+ 1.18 kB Class
87
+ 848.00 B <iseq> (IMEMO)
88
+ 597.00 B String
89
+ 384.00 B <ment> (IMEMO)
90
+ 200.00 B Array
91
+ 192.00 B Hash
92
+ 80.00 B <ifunc> (IMEMO)
93
+ 80.00 B <cref> (IMEMO)
94
+ 72.00 B Date
95
+ 40.00 B Symbol
96
+ 40.00 B SomeCustomStuff
97
+
98
+ allocated objects by gem
99
+ -----------------------------------
100
+ 36 other
101
+
102
+ allocated objects by file
103
+ -----------------------------------
104
+ 36 bin/generate-report
105
+
106
+ allocated objects by location
107
+ -----------------------------------
108
+ 27 bin/generate-report:34
109
+ 1 bin/generate-report:31
110
+ 1 bin/generate-report:30
111
+ 1 bin/generate-report:28
112
+ 1 bin/generate-report:26
113
+ 1 bin/generate-report:25
114
+ 1 bin/generate-report:24
115
+ 1 bin/generate-report:23
116
+ 1 bin/generate-report:22
117
+ 1 bin/generate-report:21
118
+
119
+ allocated objects by class
120
+ -----------------------------------
121
+ 12 String
122
+ 8 <ment> (IMEMO)
123
+ 4 Array
124
+ 2 Class
125
+ 2 <iseq> (IMEMO)
126
+ 2 <ifunc> (IMEMO)
127
+ 2 <cref> (IMEMO)
128
+ 1 Symbol
129
+ 1 SomeCustomStuff
130
+ 1 Hash
131
+ 1 Date
132
+
133
+ retained memory by gem
134
+ -----------------------------------
135
+ 808.00 B other
136
+
137
+ retained memory by file
138
+ -----------------------------------
139
+ 808.00 B bin/generate-report
140
+
141
+ retained memory by location
142
+ -----------------------------------
143
+ 168.00 B bin/generate-report:30
144
+ 168.00 B bin/generate-report:28
145
+ 160.00 B bin/generate-report:34
146
+ 80.00 B bin/generate-report:21
147
+ 72.00 B bin/generate-report:26
148
+ 40.00 B bin/generate-report:25
149
+ 40.00 B bin/generate-report:24
150
+ 40.00 B bin/generate-report:23
151
+ 40.00 B bin/generate-report:22
152
+
153
+ retained memory by class
154
+ -----------------------------------
155
+ 336.00 B Hash
156
+ 240.00 B String
157
+ 80.00 B Array
158
+ 72.00 B Date
159
+ 40.00 B Symbol
160
+ 40.00 B SomeCustomStuff
161
+
162
+ retained objects by gem
163
+ -----------------------------------
164
+ 12 other
165
+
166
+ retained objects by file
167
+ -----------------------------------
168
+ 12 bin/generate-report
169
+
170
+ retained objects by location
171
+ -----------------------------------
172
+ 4 bin/generate-report:34
173
+ 1 bin/generate-report:30
174
+ 1 bin/generate-report:28
175
+ 1 bin/generate-report:26
176
+ 1 bin/generate-report:25
177
+ 1 bin/generate-report:24
178
+ 1 bin/generate-report:23
179
+ 1 bin/generate-report:22
180
+ 1 bin/generate-report:21
181
+
182
+ retained objects by class
183
+ -----------------------------------
184
+ 6 String
185
+ 2 Hash
186
+ 1 Symbol
187
+ 1 SomeCustomStuff
188
+ 1 Date
189
+ 1 Array
190
+
191
+ Allocated String Report
192
+ -----------------------------------
193
+ 80.00 B 2 "foo="
194
+ 2 bin/generate-report:34
195
+
196
+ 80.00 B 2 "foo"
197
+ 2 bin/generate-report:34
198
+
199
+ 80.00 B 2 "bar="
200
+ 2 bin/generate-report:34
201
+
202
+ 80.00 B 2 "I am retained"
203
+ 1 bin/generate-report:23
204
+ 1 bin/generate-report:22
205
+
206
+ 40.00 B 1 "I am retained too"
207
+ 1 bin/generate-report:24
208
+
209
+ 40.00 B 1 "I am allocated too"
210
+ 1 bin/generate-report:31
211
+
212
+ 40.00 B 1 "I am allocated"
213
+ 1 bin/generate-report:30
214
+
215
+ 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 "
216
+ 1 bin/generate-report:28
217
+
218
+
219
+ Retained String Report
220
+ -----------------------------------
221
+ 80.00 B 2 "I am retained"
222
+ 1 bin/generate-report:23
223
+ 1 bin/generate-report:22
224
+
225
+ 40.00 B 1 "foo="
226
+ 1 bin/generate-report:34
227
+
228
+ 40.00 B 1 "foo"
229
+ 1 bin/generate-report:34
230
+
231
+ 40.00 B 1 "bar="
232
+ 1 bin/generate-report:34
233
+
234
+ 40.00 B 1 "I am retained too"
235
+ 1 bin/generate-report:24
236
+ ```
237
+
238
+ ### Heap Analysis
239
+
240
+ Alternatively if you with to analyse the entire heap of your Ruby process.
241
+
242
+ 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.
243
+
244
+ ```ruby
245
+ require 'objspace'
246
+ ObjectSpace.trace_object_allocations_start
247
+ ```
248
+
249
+ Then to dump the heap:
250
+
251
+ ```ruby
252
+ require 'objspace'
253
+ ObjectSpace.dump_all(output: File.open('path/to/file.heap', 'w+'))
254
+ ```
255
+
256
+ Then run `heap-profiler` against it:
257
+
258
+ ```bash
259
+ heap-profiler path/to/file.heap
260
+ ```
261
+
262
+ ## How is it different from memory_profiler?
263
+
264
+ `heap-profiler` is heavilly inspired of `memory_profiler`, it aims at being as similar as possible.
265
+ However it uses a different Ruby API to gather data.
266
+
267
+ `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
268
+ 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`.
269
+
270
+ 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
271
+ does serialize every objects, including internal ones, into JSON files. This leads to more exhaustive reports.
272
+
273
+ ## Development
274
+
275
+ 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.
276
+
277
+ 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).
278
+
279
+ ## Contributing
280
+
281
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/heap-profiler.
282
+
283
+ ## Thanks
284
+
285
+ 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).
286
+
287
+ 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).
288
+
289
+ ## License
290
+
291
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+ require "rake/extensiontask"
5
+
6
+ Rake::ExtensionTask.new("heap_profiler") do |ext|
7
+ ext.ext_dir = 'ext/heap_profiler'
8
+ ext.lib_dir = "lib/heap_profiler"
9
+ end
10
+
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.libs << "test"
13
+ t.libs << "lib"
14
+ t.test_files = FileList["test/**/*_test.rb"]
15
+ end
16
+
17
+ task default: %i(compile test)
data/TODO.md ADDED
@@ -0,0 +1,3 @@
1
+ ### Explore
2
+
3
+ - Detect object growth?
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "benchmark/ips"
6
+ require "heap_profiler/full"
7
+
8
+ native = HeapProfiler::Parser::Native.new
9
+ ruby = HeapProfiler::Parser::Ruby.new
10
+
11
+ Benchmark.ips do |x|
12
+ x.report("ruby") { ruby.parse_address("0x7f921e88a8f8") }
13
+ x.report("cpp") { native.parse_address("0x7f921e88a8f8") }
14
+ x.compare!
15
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "benchmark/ips"
6
+ require "heap_profiler/full"
7
+
8
+ FIXTURE_PATH = File.expand_path("../../test/fixtures/diffed-heap/allocated.heap", __FILE__)
9
+
10
+ native = HeapProfiler::Parser::Native.new
11
+ ruby = HeapProfiler::Parser::Ruby.new
12
+
13
+ Benchmark.ips do |x|
14
+ x.report("ruby") { ruby.build_index(FIXTURE_PATH) }
15
+ x.report("cpp") { native.build_index(FIXTURE_PATH) }
16
+ x.compare!
17
+ end
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "heap-profiler"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ require 'bundler/setup'
4
+ require "heap-profiler"
5
+ require 'fileutils'
6
+ require 'date'
7
+
8
+ class SomeCustomStuff
9
+ def initialize
10
+ @root = 1
11
+ end
12
+
13
+ def foo
14
+ @foo = 1
15
+ end
16
+
17
+ def bar
18
+ @bar = 2
19
+ end
20
+ end
21
+
22
+ $freed_objects = [+"i am free", +"i am free too"]
23
+
24
+ dir = ARGV.first
25
+ FileUtils.mkdir_p(dir)
26
+ FileUtils.rm_rf(Dir[File.join(dir, '*')])
27
+
28
+ if ARGV[1] == '--empty'
29
+ HeapProfiler.report(dir) {}
30
+ else
31
+ HeapProfiler.report(dir) do
32
+ SomeCustomStuff.new.tap(&:foo).tap(&:bar)
33
+ SomeCustomStuff.new.tap(&:bar)
34
+ $retained_objects = [
35
+ +"I am retained",
36
+ +"I am retained",
37
+ +"I am retained too",
38
+ SomeCustomStuff.new,
39
+ Date.today,
40
+ ]
41
+ "I am a very very long string " * 4
42
+ [
43
+ +"I am allocated",
44
+ +"I am allocated too",
45
+ ]
46
+ $freed_objects = nil
47
+ Struct.new("foo".to_sym, :bar)
48
+ end
49
+ end