jruby_gc_stats 0.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README.txt +31 -0
  2. data/lib/jruby/gc_stats.rb +138 -0
  3. metadata +63 -0
@@ -0,0 +1,31 @@
1
+ Title: jruby-gc-stats
2
+
3
+ Description:
4
+
5
+ This is a set of GC-monitoring methods for JRuby that mimic behavior of Ruby
6
+ Enterprise Edition's GC methods. In our case, these are all implemented in
7
+ Ruby, using the JVM's built-in monitoring and management APIs.
8
+
9
+ Example Usage:
10
+
11
+ require 'jruby/gc_stats'
12
+
13
+ require 'pp'
14
+ puts "Enabling stats..."
15
+ GC.enable_stats
16
+ puts "allocation size: #{GC.allocation_size}"
17
+ puts "Running loop..."
18
+ 1_000.times {
19
+ ary = []
20
+ 1_000.times {ary << 'foo' + 'bar'}
21
+ }
22
+ puts "collections: #{GC.collections}"
23
+ puts "time: #{GC.time}ms"
24
+ puts "bytes since last GC: #{GC.growth}"
25
+ puts "size change: #{GC.allocation_size}"
26
+ puts "Dumping..."
27
+ GC.dump
28
+
29
+ puts "Dumping caller for all threads..."
30
+ 2.times {Thread.new {sleep}}
31
+ pp caller_for_all_threads
@@ -0,0 +1,138 @@
1
+ require 'java'
2
+ require 'jruby'
3
+
4
+ module GC
5
+ import java.lang.management.ManagementFactory
6
+ import java.lang.management.MemoryType
7
+ GC_MBEANS = ManagementFactory.garbage_collector_mxbeans
8
+ POOL_MBEANS = ManagementFactory.memory_pool_mxbeans
9
+
10
+ # no perf penalty for stats on JVM, but save current counts
11
+ def self.enable_stats
12
+ @enabled = true
13
+ @start_count = _collection_count
14
+ @start_time = _collection_time
15
+ @start_size = _total_pool_size
16
+ end
17
+ def self.disable_stats
18
+ @enabled = false
19
+ end
20
+
21
+ # Number of GC runs since stat collection started.
22
+ # This is accumulated across all GCs in the system.
23
+ def self.collections
24
+ raise "GC stats are not enabled" unless @enabled
25
+ new_count = _collection_count
26
+ new_count - @start_count
27
+ end
28
+
29
+ # Amount of time spent in GC since stat collection started
30
+ # This is accumulated across all GCs in the system.
31
+ def self.time
32
+ raise "GC stats are not enabled" unless @enabled
33
+ new_time = _collection_time
34
+ new_time - @start_time
35
+ end
36
+
37
+ # Number of heap bytes requested since the last GC run.
38
+ # This includes all memory pools.
39
+ def self.growth
40
+ _usage_versus_collected
41
+ end
42
+
43
+ # Dumping the basic data for each pool
44
+ def self.dump
45
+ filename = ENV['RUBY_GC_DATA_FILE']
46
+ begin
47
+ file = filename ? File.open(filename, 'w') : $stderr
48
+ for pool_bean in POOL_MBEANS
49
+ file.puts "Name: #{pool_bean.name}"
50
+ file.puts " Type: #{pool_bean.type}"
51
+ file.puts " Peak usage: #{pool_bean.peak_usage}"
52
+ file.puts " Current usage: #{pool_bean.usage}"
53
+ file.puts " Usage after last collection: #{pool_bean.collection_usage}"
54
+ file.puts " Managers: #{pool_bean.memory_manager_names.to_a.join(', ')}"
55
+ end
56
+ ensure
57
+ file.close if filename
58
+ end
59
+ end
60
+
61
+ # A delta in the committed (active main memory) size of all memory pools
62
+ def self.allocation_size
63
+ new_size = _total_pool_size
64
+ new_size - @start_size
65
+ end
66
+
67
+ def self.num_allocations
68
+ # not sure this can be tracked on JVM; allocations happen all over
69
+ end
70
+
71
+ private
72
+
73
+ def self._collection_count
74
+ GC_MBEANS.inject(0) {|tot, bean| tot + bean.collection_count}
75
+ end
76
+
77
+ def self._collection_time
78
+ GC_MBEANS.inject(0) {|tot, bean| tot + bean.collection_time}
79
+ end
80
+
81
+ def self._usage_versus_collected
82
+ POOL_MBEANS.inject(0) do |tot, bean|
83
+ next tot if bean.type == MemoryType::NON_HEAP
84
+ tot + (bean.usage.used - bean.collection_usage.used)
85
+ end
86
+ end
87
+
88
+ def self._total_pool_size
89
+ POOL_MBEANS.inject(0) do |tot, bean|
90
+ tot + bean.usage.committed
91
+ end
92
+ end
93
+ end
94
+
95
+ module ObjectSpace
96
+ def self.live_objects
97
+ # not sure if there's a way to get this without tooling API on JVM
98
+ end
99
+
100
+ def self.allocated_objects
101
+ # ditto
102
+ end
103
+ end
104
+
105
+ class Object
106
+ def caller_for_all_threads
107
+ backtraces = {}
108
+ ts = JRuby.runtime.thread_service
109
+ ts.active_ruby_threads.each do |rthread|
110
+ tc = ts.get_thread_context_for_thread(rthread)
111
+ caller = tc.create_caller_backtrace(JRuby.runtime, 0)
112
+ backtraces[rthread] = caller
113
+ end
114
+ backtraces
115
+ end
116
+ end
117
+
118
+ if $0 == __FILE__
119
+ require 'pp'
120
+ puts "Enabling stats..."
121
+ GC.enable_stats
122
+ puts "allocation size: #{GC.allocation_size}"
123
+ puts "Running loop..."
124
+ 1_000.times {
125
+ ary = []
126
+ 1_000.times {ary << 'foo' + 'bar'}
127
+ }
128
+ puts "collections: #{GC.collections}"
129
+ puts "time: #{GC.time}ms"
130
+ puts "bytes since last GC: #{GC.growth}"
131
+ puts "size change: #{GC.allocation_size}"
132
+ puts "Dumping..."
133
+ GC.dump
134
+
135
+ puts "Dumping caller for all threads..."
136
+ 2.times {Thread.new {sleep}}
137
+ pp caller_for_all_threads
138
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jruby_gc_stats
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ version: "0.1"
9
+ platform: java
10
+ authors:
11
+ - Charles Oliver Nutter
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2010-04-24 19:01:44.476000 -05:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description: A set of GC-monitoring methods for JRuby similar to those in Ruby Enterprise Edition
21
+ email:
22
+ - headius@headius.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.txt
29
+ files:
30
+ - lib/jruby/gc_stats.rb
31
+ - README.txt
32
+ has_rdoc: true
33
+ homepage: http://github.com/headius/jruby_gc_stats
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.3.6
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: A set of GC-monitoring methods for JRuby similar to those in Ruby Enterprise Edition
62
+ test_files: []
63
+