memprof2 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: 70b0b317e5659917d244b780e9c03035c1c06792
4
- data.tar.gz: 10d94aa32210670aecb272e61fa1264cbde82446
3
+ metadata.gz: 8f7d49694ae39d219aa3825bdbdf5a5dffbae4ea
4
+ data.tar.gz: cf598a824cdbf2d424062f7b0a94e790ba8beacc
5
5
  SHA512:
6
- metadata.gz: 7605deeb9ea4cbdabdd69c00eeee95e827f3ee138d6618945641a8dd29c5317fcdafc7f8c1307acb88b1543648a8f0355c5cbd83e5aaf6b2e3cd22b0916abf01
7
- data.tar.gz: 80dfd4f07fe669765e2f983961cae0b517289d69203d64303cb8c3cd68496e5acff0252e26a056f025e595d83d9cc9505fb919fe6676cd04d8e7f1d73c2f5abd
6
+ metadata.gz: e31eaf801bff2ec8f2d39da44554be1c65f661d3eb46d53debff04243db77945b3883be0dd7af90a2ae64a24f1e292fd86126bd329566e57f8ce546ac338150d
7
+ data.tar.gz: 470ce1c09df87bc05f5635f532f1b9fadf692ae863115cdebad5c896331f8934cc4864ad013327d88d65eb6c3a70a571201726958de3b062082e25d5fd4be45f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.0.2 (2014/12/12)
2
+
3
+ Enhancements
4
+
5
+ * Add `Memprof2.report!` to clear out tracking data after printing out results.
6
+
1
7
  # 0.0.1
2
8
 
3
9
  Initial version
data/README.md CHANGED
@@ -28,35 +28,43 @@ $ bundle
28
28
 
29
29
  ## Memprof2.report
30
30
 
31
- Memprof2.start
32
- 12.times{ "abc" }
33
- Memprof2.report(out: "/path/to/file")
34
- Memprof2.stop
31
+ ```ruby
32
+ Memprof2.start
33
+ 12.times{ "abc" }
34
+ Memprof2.report(out: "/path/to/file")
35
+ Memprof2.stop
36
+ ```
35
37
 
36
38
  Start tracking file/line memory size (bytes) information for objects created after calling `Memprof2.start`, and print out a summary of file:line:class pairs created.
37
39
 
38
- 480 file.rb:2:String
40
+ ```
41
+ 480 file.rb:2:String
42
+ ```
39
43
 
40
44
  *Note*: Call `Memprof2.report` again after `GC.start` to see which objects are cleaned up by the garbage collector:
41
45
 
42
- Memprof2.start
43
- 10.times{ $last_str = "abc" }
46
+ ```ruby
47
+ Memprof2.start
48
+ 10.times{ $last_str = "abc" }
44
49
 
45
- puts '=== Before GC'
46
- Memprof2.report
50
+ puts '=== Before GC'
51
+ Memprof2.report
47
52
 
48
- puts '=== After GC'
49
- GC.start
50
- Memprof2.report
53
+ puts '=== After GC'
54
+ GC.start
55
+ Memprof2.report
51
56
 
52
- Memprof2.stop
57
+ Memprof2.stop
58
+ ```
53
59
 
54
60
  After `GC.start`, only the very last instance of `"abc"` will still exist:
55
61
 
56
- === Before GC
57
- 400 file.rb:2:String
58
- === After GC
59
- 40 file.rb:2:String
62
+ ```
63
+ === Before GC
64
+ 400 file.rb:2:String
65
+ === After GC
66
+ 40 file.rb:2:String
67
+ ```
60
68
 
61
69
  *Note*: Use `Memprof2.report!` to clear out tracking data after printing out results.
62
70
 
@@ -64,18 +72,22 @@ After `GC.start`, only the very last instance of `"abc"` will still exist:
64
72
 
65
73
  Simple wrapper for `Memprof2.start/stop` that will start/stop memprof around a given block of ruby code.
66
74
 
67
- Memprof2.run do
68
- 100.times{ "abc" }
69
- 100.times{ 1.23 + 1 }
70
- 100.times{ Module.new }
71
- Memprof2.report(out: "/path/to/file")
72
- end
75
+ ```ruby
76
+ Memprof2.run do
77
+ 100.times{ "abc" }
78
+ 100.times{ 1.23 + 1 }
79
+ 100.times{ Module.new }
80
+ Memprof2.report(out: "/path/to/file")
81
+ end
82
+ ```
73
83
 
74
84
  For the block of ruby code, print out file:line:class pairs for ruby objects created.
75
85
 
76
- 4000 file.rb:2:String
77
- 4000 file.rb:3:Float
78
- 4000 file.rb:4:Module
86
+ ```
87
+ 4000 file.rb:2:String
88
+ 4000 file.rb:3:Float
89
+ 4000 file.rb:4:Module
90
+ ```
79
91
 
80
92
  *Note*: You can call GC.start at the end of the block to print out only objects that are 'leaking' (i.e. objects that still have inbound references).
81
93
 
data/lib/memprof2.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'objspace'
2
2
 
3
- module Memprof2
3
+ class Memprof2
4
4
  class << self
5
5
  def start
6
6
  ObjectSpace.trace_object_allocations_start
@@ -15,38 +15,57 @@ module Memprof2
15
15
  ObjectSpace.trace_object_allocations(&block)
16
16
  end
17
17
 
18
- def report(opts={})
18
+ def report(opts = {})
19
19
  ObjectSpace.trace_object_allocations_stop
20
- @rvalue_size = GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
21
- if @trace = opts[:trace]
22
- raise ArgumentError, "`trace` option must be a Regexp object" unless @trace.is_a?(Regexp)
23
- end
24
- if @ignore = opts[:ignore]
25
- raise ArgumentError, "`trace` option must be a Regexp object" unless @ignore.is_a?(Regexp)
26
- end
27
- results = {}
28
- ObjectSpace.each_object do |o|
29
- next unless (file = ObjectSpace.allocation_sourcefile(o))
30
- next if file == __FILE__
31
- next if (@trace and @trace !~ file)
32
- next if (@ignore and @ignore =~ file)
33
- line = ObjectSpace.allocation_sourceline(o)
34
- memsize = ObjectSpace.memsize_of(o) + @rvalue_size
35
- memsize = @rvalue_size if memsize > 100_000_000_000 # compensate for API bug
36
- klass = o.class.name rescue "BasicObject"
37
- location = "#{file}:#{line}:#{klass}"
38
- results[location] ||= 0
39
- results[location] += memsize
40
- end
41
- @out = opts[:out] || "/dev/stdout"
42
- File.open(@out, 'w') do |io|
43
- results.each do |location, memsize|
44
- io.puts "#{memsize} #{location}"
45
- end
46
- end
20
+ self.new.report(opts)
47
21
  ensure
48
22
  ObjectSpace.trace_object_allocations_start
49
23
  end
24
+
25
+ def report!(opts = {})
26
+ report(opts)
27
+ ObjectSpace.trace_object_allocations_clear
28
+ end
29
+ end
30
+
31
+ def report(opts={})
32
+ configure(opts)
33
+ results = collect_info
34
+ File.open(@out, 'w') do |io|
35
+ results.each do |location, memsize|
36
+ io.puts "#{memsize} #{location}"
37
+ end
38
+ end
39
+ end
40
+
41
+ def configure(opts = {})
42
+ @rvalue_size = GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
43
+ if @trace = opts[:trace]
44
+ raise ArgumentError, "`trace` option must be a Regexp object" unless @trace.is_a?(Regexp)
45
+ end
46
+ if @ignore = opts[:ignore]
47
+ raise ArgumentError, "`ignore` option must be a Regexp object" unless @ignore.is_a?(Regexp)
48
+ end
49
+ @out = opts[:out] || "/dev/stdout"
50
+ self
51
+ end
52
+
53
+ def collect_info
54
+ results = {}
55
+ ObjectSpace.each_object do |o|
56
+ next unless (file = ObjectSpace.allocation_sourcefile(o))
57
+ next if file == __FILE__
58
+ next if (@trace and @trace !~ file)
59
+ next if (@ignore and @ignore =~ file)
60
+ line = ObjectSpace.allocation_sourceline(o)
61
+ memsize = ObjectSpace.memsize_of(o) + @rvalue_size
62
+ memsize = @rvalue_size if memsize > 100_000_000_000 # compensate for API bug
63
+ klass = o.class.name rescue "BasicObject"
64
+ location = "#{file}:#{line}:#{klass}"
65
+ results[location] ||= 0
66
+ results[location] += memsize
67
+ end
68
+ results
50
69
  end
51
70
  end
52
71
 
data/memprof2.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "memprof2"
3
- spec.version = "0.0.1"
3
+ spec.version = "0.0.2"
4
4
  spec.authors = ["Naotoshi Seo"]
5
5
  spec.email = ["sonots@gmail.com"]
6
6
  spec.description = %q{Ruby memory profiler for >= Ruby 2.1.0}
data/test/helper.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require 'memprof2'
@@ -0,0 +1,53 @@
1
+ require_relative 'helper'
2
+
3
+ class TestMemprof2 < Test::Unit::TestCase
4
+ def rvalue_size
5
+ GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
6
+ end
7
+
8
+ def find(results, key_match)
9
+ results.find {|k, v| k =~ key_match }.last
10
+ end
11
+
12
+ def test_start_stop
13
+ memprof = Memprof2.new.configure({})
14
+ Memprof2.start
15
+ a = "abc"
16
+ 12.times{ "abc" }
17
+ results = memprof.collect_info
18
+ Memprof2.stop
19
+ assert_equal(rvalue_size, find(results, /test_memprof2.rb:15:String/))
20
+ assert_equal(rvalue_size * 12, find(results, /test_memprof2.rb:16:String/))
21
+ end
22
+
23
+ def test_run
24
+ memprof = Memprof2.new.configure({})
25
+ results = nil
26
+ Memprof2.run do
27
+ a = "abc"
28
+ results = memprof.collect_info
29
+ end
30
+ assert_equal(rvalue_size, find(results, /test_memprof2.rb:27:String/))
31
+ end
32
+
33
+ def test_report_out
34
+ opts = {out: "tmp/test_report.out"}
35
+ Memprof2.start
36
+ a = "abc"
37
+ Memprof2.report(opts)
38
+ Memprof2.stop
39
+ assert_match("test/test_memprof2.rb:36:String\n", File.read(opts[:out]))
40
+ end
41
+
42
+ def test_report!
43
+ opts_bang = {out: "tmp/test_report_bang.out"}
44
+ opts = {out: "tmp/test_report.out"}
45
+ Memprof2.start
46
+ a = "abc"
47
+ Memprof2.report!(opts_bang) # clear
48
+ Memprof2.report(opts)
49
+ Memprof2.stop
50
+ assert_match("test/test_memprof2.rb:46:String\n", File.read(opts_bang[:out]))
51
+ assert_match("", File.read(opts[:out]))
52
+ end
53
+ end
data/tmp/.gitkeep ADDED
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: memprof2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Naotoshi Seo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-07 00:00:00.000000000 Z
11
+ date: 2014-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -55,6 +55,9 @@ files:
55
55
  - example.rb
56
56
  - lib/memprof2.rb
57
57
  - memprof2.gemspec
58
+ - test/helper.rb
59
+ - test/test_memprof2.rb
60
+ - tmp/.gitkeep
58
61
  homepage: https://github.com/sonots/memprof2
59
62
  licenses:
60
63
  - MIT
@@ -79,4 +82,6 @@ rubygems_version: 2.2.2
79
82
  signing_key:
80
83
  specification_version: 4
81
84
  summary: Ruby memory profiler for >= Ruby 2.1.0
82
- test_files: []
85
+ test_files:
86
+ - test/helper.rb
87
+ - test/test_memprof2.rb