memprof2 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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