jruby_gc_stats 0.1-java

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.
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
+