leak_profiler 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c65071dbbe8a5516095022d27fc86043512d1f2a1c12c8fcf24d9c3aea7e0a71
4
- data.tar.gz: e2ba069b4a7b4ed7c369b72756ec8f97f2f32736ea212ae7092802d0e4aecf94
3
+ metadata.gz: 3e7942b0713d364d60dcfbeb171894c69aa63028adc6795d4b48e85d6019152d
4
+ data.tar.gz: '05967d0eefaf0301b380620c23b5eb925ac62a26ad45c1504a7ff2e6690f537a'
5
5
  SHA512:
6
- metadata.gz: e3b875bd325d8ab5c36004b0c413ff7eeb742211e058669a5fd328dfe1ff654672b69a84cb4d627663085e37c0a540a881d36e40eb65c9a48e2b85fb23a99304
7
- data.tar.gz: 6f26582f06e662a12ed60282fc41b78303de00ccd1350469e99565ec54ba142f1c68b966fea60e5294927aa724132165f9d49cdcdadba7ed2d30d478501c915f
6
+ metadata.gz: b430a5fe0d7ad6fc90d1dd1f949aeb0b2948487a6f651b4c52975774b4e5cb21ab98a9f7219e8c665f90daa3c70f6aa3d3c803ffdc9aa48acddd0e0e95d8bf15
7
+ data.tar.gz: 175e865aa10c22816d9b86c04301a0c574af0260becbe3fdf76b78d8f338b466fdc2170431a4244e0296ed47b27223879e52c60060363654f1adc8da7cd49638
data/.rubocop.yml CHANGED
@@ -14,6 +14,9 @@ Metrics:
14
14
  Style/Copyright:
15
15
  Enabled: false
16
16
 
17
+ Style/GlobalVars:
18
+ Enabled: false
19
+
17
20
  Style/ImplicitRuntimeError:
18
21
  Enabled: false
19
22
 
data/Rakefile CHANGED
@@ -1,10 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/gem_tasks'
4
+ require 'rake/extensiontask'
4
5
  require 'rake/testtask'
5
6
 
6
- task default: :test
7
+ task default: %i[compile test]
8
+
9
+ Rake::ExtensionTask.new('leak_profiler_ext') do |ext|
10
+ ext.ext_dir = 'ext/leak_profiler'
11
+ end
7
12
 
8
13
  Rake::TestTask.new do |task|
9
14
  task.pattern = 'test/test_*.rb'
10
15
  end
16
+
17
+ # Update RBS signature
18
+ task :'rbs:update' do
19
+ sh 'bundle exec rbs-inline --output lib'
20
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mkmf'
4
+
5
+ $LDFLAGS += ' -lpsapi' if RUBY_PLATFORM.include?('mingw')
6
+
7
+ create_makefile('leak_profiler_ext')
@@ -0,0 +1,37 @@
1
+ #include "ruby.h"
2
+
3
+ #if defined(_WIN32)
4
+ #include <psapi.h>
5
+
6
+ static VALUE leak_profiler_max_rss(VALUE self)
7
+ {
8
+ PROCESS_MEMORY_COUNTERS pmc;
9
+ if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
10
+ rb_sys_fail("GetProcessMemoryInfo");
11
+ }
12
+ return LONG2NUM(pmc.PeakWorkingSetSize);
13
+ }
14
+
15
+ #else
16
+ #include <sys/resource.h>
17
+
18
+ static VALUE leak_profiler_max_rss(VALUE self)
19
+ {
20
+ struct rusage usage;
21
+ if (getrusage(RUSAGE_SELF, &usage) == -1) {
22
+ rb_sys_fail("getrusage");
23
+ }
24
+
25
+ return LONG2NUM(usage.ru_maxrss);
26
+ }
27
+
28
+ #endif
29
+
30
+ void Init_leak_profiler_ext(void)
31
+ {
32
+ VALUE cLeakProfiler = rb_define_class("LeakProfiler", rb_cObject);
33
+ VALUE cMemoryUsage = rb_define_class_under(cLeakProfiler, "MemoryUsage", rb_cObject);
34
+
35
+
36
+ rb_define_singleton_method(cMemoryUsage, "max_rss", leak_profiler_max_rss, 0);
37
+ }
@@ -1,11 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rbs_inline: enabled
4
+
3
5
  require 'objspace'
4
6
 
5
7
  class LeakProfiler
6
8
  class Allocations
7
9
  attr_reader :thread
8
10
 
11
+ # @rbs logger: untyped
12
+ # @rbs interval: Integer
13
+ # @rbs max_allocations: Integer
14
+ # @rbs max_referrers: Integer
9
15
  def initialize(logger:, interval:, max_allocations:, max_referrers:)
10
16
  @logger = logger
11
17
  @interval = interval
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rbs_inline: enabled
4
+
3
5
  require_relative 'allocations'
4
6
  require_relative 'memory_memsize'
5
7
  require_relative 'memory_usage'
@@ -7,6 +9,8 @@ require 'fileutils'
7
9
  require 'logger'
8
10
 
9
11
  class LeakProfiler
12
+ # @rbs output_dir: String
13
+ # @rbs return: void
10
14
  def initialize(output_dir: './leak_profiler')
11
15
  @output_dir = output_dir
12
16
  @threads = []
@@ -14,6 +18,12 @@ class LeakProfiler
14
18
  FileUtils.mkdir_p(@output_dir)
15
19
  end
16
20
 
21
+ # @rbs interval: Integer
22
+ # @rbs max_allocations: Integer
23
+ # @rbs max_referrers: Integer
24
+ # @rbs logger: untyped
25
+ # @rbs filename: String
26
+ # @rbs return: self
17
27
  def report(interval: 30, max_allocations: 10, max_referrers: 3, logger: nil, filename: nil)
18
28
  filename ||= "leak_profiler-#{Process.pid}.log"
19
29
  logger ||= Logger.new(File.join(@output_dir, filename))
@@ -24,6 +34,9 @@ class LeakProfiler
24
34
  self
25
35
  end
26
36
 
37
+ # @rbs interval: Integer
38
+ # @rbs filename: String
39
+ # @rbs return: self
27
40
  def report_rss(interval: 1, filename: nil)
28
41
  profiler = LeakProfiler::MemoryUsage.new(output_dir: @output_dir, interval: interval, filename: filename)
29
42
  profiler.report
@@ -32,6 +45,9 @@ class LeakProfiler
32
45
  self
33
46
  end
34
47
 
48
+ # @rbs interval: Integer
49
+ # @rbs filename: String
50
+ # @rbs return: self
35
51
  def report_memsize(interval: 1, filename: nil)
36
52
  profiler = LeakProfiler::MemoryMemsize.new(output_dir: @output_dir, interval: interval, filename: filename)
37
53
  profiler.report
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rbs_inline: enabled
4
+
3
5
  require 'objspace'
4
6
 
5
7
  class LeakProfiler
6
8
  class MemoryMemsize
7
9
  attr_reader :thread
8
10
 
11
+ # @rbs output_dir: String
12
+ # @rbs interval: Integer
13
+ # @rbs filename: String
9
14
  def initialize(output_dir:, interval:, filename: nil)
10
15
  @output_dir = output_dir
11
16
  @interval = interval
@@ -1,9 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rbs_inline: enabled
4
+
3
5
  class LeakProfiler
4
6
  class MemoryUsage
5
7
  attr_reader :thread
6
8
 
9
+ # @rbs output_dir: String
10
+ # @rbs interval: Integer
11
+ # @rbs filename: String
7
12
  def initialize(output_dir:, interval:, filename: nil)
8
13
  @output_dir = output_dir
9
14
  @interval = interval
@@ -11,17 +16,13 @@ class LeakProfiler
11
16
  end
12
17
 
13
18
  def report
14
- raise('Not supported Windows platform because this uses `ps` command for measurement.') if /mingw/.match?(RUBY_PLATFORM)
15
-
16
- pid = Process.pid
17
-
18
19
  @thread = Thread.start do
19
20
  i = 0
20
21
  File.open(File.expand_path(File.join(@output_dir, @filename)), 'w') do |f|
21
22
  f.puts('elapsed [sec],memory usage (rss) [MB]')
22
23
 
23
24
  loop do
24
- rss = Integer(`ps -o rss= -p #{pid}`) / 1024.0
25
+ rss = LeakProfiler::MemoryUsage.max_rss / 1024.0
25
26
  f.puts("#{i},#{rss}")
26
27
  f.fsync
27
28
  i += @interval
data/lib/leak_profiler.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'leak_profiler/leak_profiler'
4
+ require_relative 'leak_profiler_ext.so'
@@ -0,0 +1,27 @@
1
+ # Generated from lib/leak_profiler/allocations.rb with RBS::Inline
2
+
3
+ class LeakProfiler
4
+ class Allocations
5
+ attr_reader thread: untyped
6
+
7
+ # @rbs logger: untyped
8
+ # @rbs interval: Integer
9
+ # @rbs max_allocations: Integer
10
+ # @rbs max_referrers: Integer
11
+ def initialize: (logger: untyped, interval: Integer, max_allocations: Integer, max_referrers: Integer) -> untyped
12
+
13
+ def report: () -> untyped
14
+
15
+ private
16
+
17
+ def report_allocations: (untyped allocations) -> untyped
18
+
19
+ def report_referrer_objects: (untyped allocations) -> untyped
20
+
21
+ def detect_referrer_objects: (untyped object) -> untyped
22
+
23
+ def allocated_location: (untyped obj) -> untyped
24
+
25
+ def sort: (untyped allocations) -> untyped
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # Generated from lib/leak_profiler/leak_profiler.rb with RBS::Inline
2
+
3
+ class LeakProfiler
4
+ # @rbs output_dir: String
5
+ # @rbs return: void
6
+ def initialize: (?output_dir: String) -> void
7
+
8
+ # @rbs interval: Integer
9
+ # @rbs max_allocations: Integer
10
+ # @rbs max_referrers: Integer
11
+ # @rbs logger: untyped
12
+ # @rbs filename: String
13
+ # @rbs return: self
14
+ def report: (?interval: Integer, ?max_allocations: Integer, ?max_referrers: Integer, ?logger: untyped, ?filename: String) -> self
15
+
16
+ # @rbs interval: Integer
17
+ # @rbs filename: String
18
+ # @rbs return: self
19
+ def report_rss: (?interval: Integer, ?filename: String) -> self
20
+
21
+ # @rbs interval: Integer
22
+ # @rbs filename: String
23
+ # @rbs return: self
24
+ def report_memsize: (?interval: Integer, ?filename: String) -> self
25
+
26
+ def shutdown: () -> untyped
27
+ end
@@ -0,0 +1,14 @@
1
+ # Generated from lib/leak_profiler/memory_memsize.rb with RBS::Inline
2
+
3
+ class LeakProfiler
4
+ class MemoryMemsize
5
+ attr_reader thread: untyped
6
+
7
+ # @rbs output_dir: String
8
+ # @rbs interval: Integer
9
+ # @rbs filename: String
10
+ def initialize: (output_dir: String, interval: Integer, ?filename: String) -> untyped
11
+
12
+ def report: () -> untyped
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # Generated from lib/leak_profiler/memory_usage.rb with RBS::Inline
2
+
3
+ class LeakProfiler
4
+ class MemoryUsage
5
+ attr_reader thread: untyped
6
+
7
+ # @rbs output_dir: String
8
+ # @rbs interval: Integer
9
+ # @rbs filename: String
10
+ def initialize: (output_dir: String, interval: Integer, ?filename: String) -> untyped
11
+
12
+ def report: () -> untyped
13
+ end
14
+ end
@@ -1,10 +1,5 @@
1
1
  class LeakProfiler
2
- def initialize: (?output_dir: String) -> void
3
-
4
- # TODO: Use valid type for logger
5
- def report: (?interval: Integer, ?max_allocations: Integer, ?max_referrers: Integer, ?logger: Object, ?filename: String) -> self
6
-
7
- def report_rss: (?interval: Integer, ?filename: String) -> self
8
-
9
- def report_memsize: (?interval: Integer, ?filename: String) -> self
2
+ class MemoryUsage
3
+ def self.max_rss: () -> Integer
4
+ end
10
5
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'leak_profiler'
4
+ require 'minitest/autorun'
5
+
6
+ class MemoryUsageTest < Minitest::Test
7
+ def test_report_rss
8
+ assert_equal(true, LeakProfiler::MemoryUsage.max_rss.positive?)
9
+ end
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leak_profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Watson
@@ -27,7 +27,8 @@ description: A simple profiler for Ruby to detect memory leak.
27
27
  email:
28
28
  - watson1978@gmail.com
29
29
  executables: []
30
- extensions: []
30
+ extensions:
31
+ - ext/leak_profiler/extconf.rb
31
32
  extra_rdoc_files: []
32
33
  files:
33
34
  - ".rubocop.yml"
@@ -35,13 +36,20 @@ files:
35
36
  - LICENSE
36
37
  - README.md
37
38
  - Rakefile
39
+ - ext/leak_profiler/extconf.rb
40
+ - ext/leak_profiler/leak_profiler.c
38
41
  - lib/leak_profiler.rb
39
42
  - lib/leak_profiler/allocations.rb
40
43
  - lib/leak_profiler/leak_profiler.rb
41
44
  - lib/leak_profiler/memory_memsize.rb
42
45
  - lib/leak_profiler/memory_usage.rb
46
+ - sig/generated/leak_profiler/allocations.rbs
47
+ - sig/generated/leak_profiler/leak_profiler.rbs
48
+ - sig/generated/leak_profiler/memory_memsize.rbs
49
+ - sig/generated/leak_profiler/memory_usage.rbs
43
50
  - sig/leak_profiler.rbs
44
51
  - test/test_leak_profiler.rb
52
+ - test/test_memory_usage.rb
45
53
  homepage: https://github.com/Watson1978/leak_profiler
46
54
  licenses:
47
55
  - MIT
@@ -63,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
71
  - !ruby/object:Gem::Version
64
72
  version: '0'
65
73
  requirements: []
66
- rubygems_version: 3.6.8
74
+ rubygems_version: 3.6.7
67
75
  specification_version: 4
68
76
  summary: A simple profiler for Ruby to detect memory leak.
69
77
  test_files: []