leak_profiler 0.7.6 → 0.8.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 +4 -4
- data/.rubocop.yml +4 -1
- data/README.md +2 -0
- data/Rakefile +1 -1
- data/lib/leak_profiler/allocations.rb +19 -5
- data/lib/leak_profiler/leak_profiler.rb +4 -2
- data/sig/generated/leak_profiler/allocations.rbs +4 -2
- data/sig/generated/leak_profiler/leak_profiler.rbs +3 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8f865010e37ad98c3d1dfc80fde69b7d3a32ef06a2166dca3c38d0829c7f17fe
|
|
4
|
+
data.tar.gz: 5939197c9c2824d56b3d520a8106c4070694f8a5ba66575eb021ea8223a2f8f8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c4374a43ebbb3261281172d3ec46ba575c5707c82bca657501c5c3fe72dbae0ff3d384a5ce53179e7dd4d55e2aef256391c88484d7ea947da45477e7a06aa082
|
|
7
|
+
data.tar.gz: 91e28f5b4284598bb44ee9dde9306fbf2f6d46fe41a3ad3b7cce3c94d32315db249c8a6c427e0a9b01d76c73c196249efdc03aa23eea311811fac304764f2568
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
|
@@ -64,6 +64,8 @@ Referrers ----------------------------------------------------------------------
|
|
|
64
64
|
* `interval` (default `30`): The interval in seconds for report.
|
|
65
65
|
* `max_allocations` (default `10`): Outputs the specified number of objects that use a lot of memory.
|
|
66
66
|
* `max_referrers` (default `3`): Outputs the number of references in order of the amount of memory used.
|
|
67
|
+
* `max_sample_objects` (default `100`): Sampling objects to detect referrer.
|
|
68
|
+
* `run_gc` (default `false`): Whether to invoke `GC.start` before logging to exclude temporary objects from the metrics.
|
|
67
69
|
* `logger` (defalut `nil`): Specify the logger object if you want to use custom logger.
|
|
68
70
|
* `filename` (defalut `nil`): Specify the filename if you want to use custom filename.
|
|
69
71
|
|
data/Rakefile
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# rbs_inline: enabled
|
|
4
4
|
|
|
5
5
|
require 'objspace'
|
|
6
|
+
require 'set'
|
|
6
7
|
|
|
7
8
|
class LeakProfiler
|
|
8
9
|
class Allocations
|
|
@@ -15,11 +16,15 @@ class LeakProfiler
|
|
|
15
16
|
# @rbs interval: Integer
|
|
16
17
|
# @rbs max_allocations: Integer
|
|
17
18
|
# @rbs max_referrers: Integer
|
|
18
|
-
|
|
19
|
+
# @rbs max_sample_objects: Integer
|
|
20
|
+
# @rbs run_gc: bool
|
|
21
|
+
def initialize(logger:, interval:, max_allocations:, max_referrers:, max_sample_objects:, run_gc: false)
|
|
19
22
|
@logger = logger
|
|
20
23
|
@interval = interval
|
|
21
24
|
@max_allocations = max_allocations
|
|
22
25
|
@max_referrers = max_referrers
|
|
26
|
+
@max_sample_objects = max_sample_objects
|
|
27
|
+
@run_gc = run_gc
|
|
23
28
|
end
|
|
24
29
|
|
|
25
30
|
def report
|
|
@@ -29,6 +34,8 @@ class LeakProfiler
|
|
|
29
34
|
sleep(@interval)
|
|
30
35
|
ObjectSpace.trace_object_allocations_stop
|
|
31
36
|
|
|
37
|
+
GC.start if @run_gc
|
|
38
|
+
|
|
32
39
|
allocations = Hash.new { |h, k| h[k] = {} }
|
|
33
40
|
allocations_by_class = Hash.new { |h, k| h[k] = 0 }
|
|
34
41
|
|
|
@@ -44,7 +51,12 @@ class LeakProfiler
|
|
|
44
51
|
allocations[key][:metrics][:count] += 1
|
|
45
52
|
allocations[key][:metrics][:bytes] += ObjectSpace.memsize_of(obj)
|
|
46
53
|
|
|
47
|
-
allocations[key][:
|
|
54
|
+
allocations[key][:sample_objects] ||= []
|
|
55
|
+
allocations[key][:sample_objects] << obj
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
allocations.each_value do |v|
|
|
59
|
+
v[:sample_objects] = v[:sample_objects].sample(@max_sample_objects)
|
|
48
60
|
end
|
|
49
61
|
|
|
50
62
|
report_allocations_class(allocations_by_class)
|
|
@@ -88,7 +100,7 @@ class LeakProfiler
|
|
|
88
100
|
|
|
89
101
|
objs = allocations.reject { |k, _| k == UNKNOWN }
|
|
90
102
|
sort(objs).take(@max_referrers).each do |key, value|
|
|
91
|
-
referrer_objects = detect_referrer_objects(value[:
|
|
103
|
+
referrer_objects = detect_referrer_objects(value[:sample_objects])
|
|
92
104
|
|
|
93
105
|
logs = referrer_objects.map do |r|
|
|
94
106
|
klass = obj_class(r[:referrer_object])
|
|
@@ -102,12 +114,14 @@ class LeakProfiler
|
|
|
102
114
|
end
|
|
103
115
|
end
|
|
104
116
|
|
|
105
|
-
def detect_referrer_objects(
|
|
117
|
+
def detect_referrer_objects(objects)
|
|
106
118
|
referrer_objects = []
|
|
119
|
+
objects_ids = objects.to_set(&:object_id)
|
|
120
|
+
|
|
107
121
|
ObjectSpace.each_object.each do |obj|
|
|
108
122
|
r = ObjectSpace.reachable_objects_from(obj)
|
|
109
123
|
begin
|
|
110
|
-
if r&.any? { |o|
|
|
124
|
+
if r&.any? { |o| objects_ids.include?(o.object_id) }
|
|
111
125
|
key = allocated_location(obj)
|
|
112
126
|
referrer_objects << { referrer_object: obj, referrer_object_allocated_line: key }
|
|
113
127
|
end
|
|
@@ -21,13 +21,15 @@ class LeakProfiler
|
|
|
21
21
|
# @rbs interval: Integer
|
|
22
22
|
# @rbs max_allocations: Integer
|
|
23
23
|
# @rbs max_referrers: Integer
|
|
24
|
+
# @rbs max_sample_objects: Integer
|
|
25
|
+
# @rbs run_gc: bool
|
|
24
26
|
# @rbs logger: untyped
|
|
25
27
|
# @rbs filename: String
|
|
26
28
|
# @rbs return: self
|
|
27
|
-
def report(interval: 30, max_allocations: 10, max_referrers: 3, logger: nil, filename: nil)
|
|
29
|
+
def report(interval: 30, max_allocations: 10, max_referrers: 3, max_sample_objects: 100, run_gc: false, logger: nil, filename: nil)
|
|
28
30
|
filename ||= "leak_profiler-#{Process.pid}.log"
|
|
29
31
|
logger ||= Logger.new(File.join(@output_dir, filename))
|
|
30
|
-
profiler = LeakProfiler::Allocations.new(logger: logger, interval: interval, max_allocations: max_allocations, max_referrers: max_referrers)
|
|
32
|
+
profiler = LeakProfiler::Allocations.new(logger: logger, interval: interval, max_allocations: max_allocations, max_referrers: max_referrers, max_sample_objects: max_sample_objects, run_gc: run_gc)
|
|
31
33
|
profiler.report
|
|
32
34
|
@threads << profiler.thread
|
|
33
35
|
|
|
@@ -10,7 +10,9 @@ class LeakProfiler
|
|
|
10
10
|
# @rbs interval: Integer
|
|
11
11
|
# @rbs max_allocations: Integer
|
|
12
12
|
# @rbs max_referrers: Integer
|
|
13
|
-
|
|
13
|
+
# @rbs max_sample_objects: Integer
|
|
14
|
+
# @rbs run_gc: bool
|
|
15
|
+
def initialize: (logger: untyped, interval: Integer, max_allocations: Integer, max_referrers: Integer, max_sample_objects: Integer, ?run_gc: bool) -> untyped
|
|
14
16
|
|
|
15
17
|
def report: () -> untyped
|
|
16
18
|
|
|
@@ -22,7 +24,7 @@ class LeakProfiler
|
|
|
22
24
|
|
|
23
25
|
def report_referrer_objects: (untyped allocations) -> untyped
|
|
24
26
|
|
|
25
|
-
def detect_referrer_objects: (untyped
|
|
27
|
+
def detect_referrer_objects: (untyped objects) -> untyped
|
|
26
28
|
|
|
27
29
|
def allocated_location: (untyped obj) -> untyped
|
|
28
30
|
|
|
@@ -8,10 +8,12 @@ class LeakProfiler
|
|
|
8
8
|
# @rbs interval: Integer
|
|
9
9
|
# @rbs max_allocations: Integer
|
|
10
10
|
# @rbs max_referrers: Integer
|
|
11
|
+
# @rbs max_sample_objects: Integer
|
|
12
|
+
# @rbs run_gc: bool
|
|
11
13
|
# @rbs logger: untyped
|
|
12
14
|
# @rbs filename: String
|
|
13
15
|
# @rbs return: self
|
|
14
|
-
def report: (?interval: Integer, ?max_allocations: Integer, ?max_referrers: Integer, ?logger: untyped, ?filename: String) -> self
|
|
16
|
+
def report: (?interval: Integer, ?max_allocations: Integer, ?max_referrers: Integer, ?max_sample_objects: Integer, ?run_gc: bool, ?logger: untyped, ?filename: String) -> self
|
|
15
17
|
|
|
16
18
|
# @rbs interval: Integer
|
|
17
19
|
# @rbs filename: String
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: leak_profiler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Watson
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: logger
|
|
@@ -58,7 +57,6 @@ metadata:
|
|
|
58
57
|
homepage_uri: https://github.com/Watson1978/leak_profiler
|
|
59
58
|
source_code_uri: https://github.com/Watson1978/leak_profiler
|
|
60
59
|
rubygems_mfa_required: 'true'
|
|
61
|
-
post_install_message:
|
|
62
60
|
rdoc_options: []
|
|
63
61
|
require_paths:
|
|
64
62
|
- lib
|
|
@@ -73,8 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
73
71
|
- !ruby/object:Gem::Version
|
|
74
72
|
version: '0'
|
|
75
73
|
requirements: []
|
|
76
|
-
rubygems_version:
|
|
77
|
-
signing_key:
|
|
74
|
+
rubygems_version: 4.0.4
|
|
78
75
|
specification_version: 4
|
|
79
76
|
summary: A simple profiler for Ruby to detect memory leak.
|
|
80
77
|
test_files: []
|