heap-profiler 0.5.0 → 0.6.0
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 +4 -4
- data/.github/workflows/tests.yml +7 -33
- data/.rubocop.yml +3 -0
- data/Gemfile.lock +4 -2
- data/README.md +15 -1
- data/bin/generate-report +13 -0
- data/ext/heap_profiler/heap_profiler.cpp +12 -3
- data/ext/heap_profiler/simdjson.cpp +3472 -409
- data/ext/heap_profiler/simdjson.h +24123 -33047
- data/lib/heap_profiler/analyzer.rb +27 -1
- data/lib/heap_profiler/cli.rb +62 -9
- data/lib/heap_profiler/index.rb +1 -0
- data/lib/heap_profiler/results.rb +49 -7
- data/lib/heap_profiler/version.rb +1 -1
- metadata +3 -4
- data/.travis.yml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d471a3cfa86394c637238b8d27fb487b764862a45ef016e6de9570e9b90811ab
|
4
|
+
data.tar.gz: 05d056160722162d9e6a2866e69baba73a8eb9bc4237e0d1fc597573c15b2380
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8d5cea4cc882c00170de66aae01216b52692b60af46a2d5be64804f5565a03016716d17bbe5e413f38dceebc9b7238abaf756b50d519236044dde2f2ae1925b
|
7
|
+
data.tar.gz: 3031b322e69a2235ff388756adf89306e5dfa9cdad639bff79b122339e93b6c8b638cab8ff4f2b4c41592bfb62df05b0c32f8eb3c2a3d6c22f0963b1017cb9d0
|
data/.github/workflows/tests.yml
CHANGED
@@ -6,25 +6,12 @@ jobs:
|
|
6
6
|
name: Rubocop
|
7
7
|
runs-on: ubuntu-latest
|
8
8
|
steps:
|
9
|
-
-
|
10
|
-
|
11
|
-
|
12
|
-
- name: Setup Ruby
|
9
|
+
- uses: actions/checkout@v3
|
10
|
+
- name: Set up Ruby
|
13
11
|
uses: ruby/setup-ruby@v1
|
14
12
|
with:
|
15
13
|
ruby-version: '2.5'
|
16
|
-
|
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
|
-
|
14
|
+
bundler-cache: true
|
28
15
|
- name: Run linters
|
29
16
|
run: |
|
30
17
|
bin/rubocop -c .rubocop.yml
|
@@ -33,27 +20,14 @@ jobs:
|
|
33
20
|
runs-on: ubuntu-latest
|
34
21
|
strategy:
|
35
22
|
matrix:
|
36
|
-
ruby: [ '2.5', '2.6', '2.7', '3.0' ]
|
23
|
+
ruby: [ '2.5', '2.6', '2.7', '3.0', '3.1' ]
|
37
24
|
name: Ruby ${{ matrix.ruby }} Tests
|
38
25
|
steps:
|
39
|
-
-
|
40
|
-
|
41
|
-
|
42
|
-
- name: Setup Ruby
|
26
|
+
- uses: actions/checkout@v3
|
27
|
+
- name: Set up Ruby
|
43
28
|
uses: ruby/setup-ruby@v1
|
44
29
|
with:
|
45
30
|
ruby-version: ${{ matrix.ruby }}
|
46
|
-
|
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
|
-
|
31
|
+
bundler-cache: true
|
58
32
|
- name: Run tests
|
59
33
|
run: bundle exec rake
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
heap-profiler (0.
|
4
|
+
heap-profiler (0.6.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -18,7 +18,7 @@ GEM
|
|
18
18
|
rake-compiler (1.1.1)
|
19
19
|
rake
|
20
20
|
regexp_parser (2.0.3)
|
21
|
-
rexml (3.2.
|
21
|
+
rexml (3.2.5)
|
22
22
|
rubocop (1.8.1)
|
23
23
|
parallel (~> 1.10)
|
24
24
|
parser (>= 3.0.0.0)
|
@@ -37,6 +37,8 @@ GEM
|
|
37
37
|
unicode-display_width (2.0.0)
|
38
38
|
|
39
39
|
PLATFORMS
|
40
|
+
arm64-darwin-21
|
41
|
+
arm64-darwin-22
|
40
42
|
x86_64-darwin-19
|
41
43
|
x86_64-darwin-20
|
42
44
|
x86_64-linux
|
data/README.md
CHANGED
@@ -41,6 +41,20 @@ To then analyse the profile, run the `heap-profiler` command against the directo
|
|
41
41
|
Note that on large applications this can take a while, but if you are profiling a production
|
42
42
|
application, you can download the profile directory and do the analysis on another machine.
|
43
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
|
+
|
44
58
|
```bash
|
45
59
|
$ heap-profiler path/to/report/directory
|
46
60
|
Total allocated: 3.72 kB (36 objects)
|
@@ -229,7 +243,7 @@ If you can, you should enable allocation tracing as early as possible during you
|
|
229
243
|
|
230
244
|
```ruby
|
231
245
|
require 'objspace'
|
232
|
-
ObjectSpace.trace_object_allocations_start
|
246
|
+
ObjectSpace.trace_object_allocations_start
|
233
247
|
```
|
234
248
|
|
235
249
|
Then to dump the heap:
|
data/bin/generate-report
CHANGED
@@ -6,6 +6,17 @@ require 'fileutils'
|
|
6
6
|
require 'date'
|
7
7
|
|
8
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
|
9
20
|
end
|
10
21
|
|
11
22
|
$freed_objects = [+"i am free", +"i am free too"]
|
@@ -18,6 +29,8 @@ if ARGV[1] == '--empty'
|
|
18
29
|
HeapProfiler.report(dir) {}
|
19
30
|
else
|
20
31
|
HeapProfiler.report(dir) do
|
32
|
+
SomeCustomStuff.new.tap(&:foo).tap(&:bar)
|
33
|
+
SomeCustomStuff.new.tap(&:bar)
|
21
34
|
$retained_objects = [
|
22
35
|
+"I am retained",
|
23
36
|
+"I am retained",
|
@@ -7,7 +7,7 @@ using namespace simdjson;
|
|
7
7
|
|
8
8
|
static VALUE rb_eHeapProfilerError, rb_eHeapProfilerCapacityError, sym_type, sym_class,
|
9
9
|
sym_address, sym_value, sym_memsize, sym_imemo_type, sym_struct, sym_file,
|
10
|
-
sym_line, sym_shared, sym_references, id_uminus;
|
10
|
+
sym_line, sym_shared, sym_references, sym_edge_name, id_uminus;
|
11
11
|
|
12
12
|
typedef struct {
|
13
13
|
dom::parser *parser;
|
@@ -190,8 +190,11 @@ static VALUE make_ruby_object(dom::object object)
|
|
190
190
|
}
|
191
191
|
|
192
192
|
std::string_view _class;
|
193
|
-
if (
|
194
|
-
|
193
|
+
if (type != "IMEMO") {
|
194
|
+
// IMEMO "class" field can sometime be junk
|
195
|
+
if (!object["class"].get(_class)) {
|
196
|
+
rb_hash_aset(hash, sym_class, INT2FIX(parse_address(_class)));
|
197
|
+
}
|
195
198
|
}
|
196
199
|
|
197
200
|
uint64_t memsize;
|
@@ -233,6 +236,11 @@ static VALUE make_ruby_object(dom::object object)
|
|
233
236
|
rb_hash_aset(hash, sym_references, references);
|
234
237
|
}
|
235
238
|
}
|
239
|
+
} else if (type == "SHAPE") {
|
240
|
+
std::string_view edge_name;
|
241
|
+
if (!object["edge_name"].get(edge_name)) {
|
242
|
+
rb_hash_aset(hash, sym_edge_name, make_string(edge_name));
|
243
|
+
}
|
236
244
|
}
|
237
245
|
|
238
246
|
std::string_view file;
|
@@ -299,6 +307,7 @@ extern "C" {
|
|
299
307
|
sym_type = ID2SYM(rb_intern("type"));
|
300
308
|
sym_class = ID2SYM(rb_intern("class"));
|
301
309
|
sym_address = ID2SYM(rb_intern("address"));
|
310
|
+
sym_edge_name = ID2SYM(rb_intern("edge_name"));
|
302
311
|
sym_value = ID2SYM(rb_intern("value"));
|
303
312
|
sym_memsize = ID2SYM(rb_intern("memsize"));
|
304
313
|
sym_struct = ID2SYM(rb_intern("struct"));
|