bleak_house 3.0.1 → 3.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/bleak_house.rb CHANGED
@@ -1,7 +1,13 @@
1
1
 
2
- require 'bleak_house/logger'
2
+ if ENV['BLEAK_HOUSE']
3
3
 
4
- if ENV['RAILS_ENV'] and ENV['BLEAK_HOUSE']
5
- require 'bleak_house/rails'
6
- BleakHouse::Rails.warn "enabled (log/bleak_house_#{RAILS_ENV}.dump)"
4
+ require 'dispatcher' # rails
5
+
6
+ require 'bleak_house/bleak_house'
7
+ require 'bleak_house/mem_logger'
8
+ require 'bleak_house/dispatcher'
9
+ require 'bleak_house/action_controller'
10
+
11
+ BleakHouse.warn "enabled (log/#{RAILS_ENV}_bleak_house.log) (#{BleakHouse.log_interval} requests per frame)"
12
+
7
13
  end
@@ -0,0 +1,13 @@
1
+
2
+ namespace :bleak_house do
3
+ desc 'Analyze and chart all data'
4
+ task :analyze do
5
+ begin
6
+ require "#{File.dirname(__FILE__)}/../lib/bleak_house/analyze"
7
+ rescue LoadError
8
+ require 'bleak_house/analyze'
9
+ end
10
+ BleakHouse::Analyze.build_all("#{RAILS_ROOT}/log/bleak_house_#{RAILS_ENV}.dump")
11
+ end
12
+ end
13
+
metadata CHANGED
@@ -1,18 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
2
+ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: bleak_house
5
5
  version: !ruby/object:Gem::Version
6
- version: 3.0.1
7
- date: 2007-09-25 00:00:00 -04:00
8
- summary: A library for finding memory leaks.
6
+ version: "3.1"
7
+ date: 2007-05-01 00:00:00 -04:00
8
+ summary: BleakHouse is a Rails plugin for finding memory leaks. It tracks ObjectSpace for your entire app, and produces charts of references by controller, by action, and by object class.
9
9
  require_paths:
10
10
  - lib
11
- - ext
12
- email: ""
13
- homepage: http://blog.evanweaver.com/files/doc/fauna/bleak_house/
11
+ email: evan at cloudbur dot st
12
+ homepage: http://blog.evanweaver.com
14
13
  rubyforge_project: fauna
15
- description: A library for finding memory leaks.
14
+ description: BleakHouse is a Rails plugin for finding memory leaks. It tracks ObjectSpace for your entire app, and produces charts of references by controller, by action, and by object class.
16
15
  autorequire:
17
16
  default_executable:
18
17
  bindir: bin
@@ -26,81 +25,55 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
26
25
  platform: ruby
27
26
  signing_key:
28
27
  cert_chain:
29
- - |
30
- -----BEGIN CERTIFICATE-----
31
- MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADA9MQ0wCwYDVQQDDARldmFu
32
- MRgwFgYKCZImiZPyLGQBGRYIY2xvdWRidXIxEjAQBgoJkiaJk/IsZAEZFgJzdDAe
33
- Fw0wNzA5MTYxMDMzMDBaFw0wODA5MTUxMDMzMDBaMD0xDTALBgNVBAMMBGV2YW4x
34
- GDAWBgoJkiaJk/IsZAEZFghjbG91ZGJ1cjESMBAGCgmSJomT8ixkARkWAnN0MIIB
35
- IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5C0Io89nyApnr+PvbNFge9Vs
36
- yRWAlGBUEMahpXp28VrrfXZT0rAW7JBo4PlCE3jl4nE4dzE6gAdItSycjTosrw7A
37
- Ir5+xoyl4Vb35adv56TIQQXvNz+BzlqnkAY5JN0CSBRTQb6mxS3hFyD/h4qgDosj
38
- R2RFVzHqSxCS8xq4Ny8uzOwOi+Xyu4w67fI5JvnPvMxqrlR1eaIQHmxnf76RzC46
39
- QO5QhufjAYGGXd960XzbQsQyTDUYJzrvT7AdOfiyZzKQykKt8dEpDn+QPjFTnGnT
40
- QmgJBX5WJN0lHF2l1sbv3gh4Kn1tZu+kTUqeXY6ShAoDTyvZRiFqQdwh8w2lTQID
41
- AQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU+WqJz3xQ
42
- XSea1hRvvHWcIMgeeC4wDQYJKoZIhvcNAQEFBQADggEBAGLZ75jfOEW8Nsl26CTt
43
- JFrWxQTcQT/UljeefVE3xYr7lc9oQjbqO3FOyued3qW7TaNEtZfSHoYeUSMYbpw1
44
- XAwocIPuSRFDGM4B+hgQGVDx8PMGiJKom4qLXjO40UZsR7QyN/u869Vj45LURm6h
45
- MBcPeqCASI+WNprj9+uZa2kmHiitrFqqfMBNlm5IFbn9XeYSta9AHVvs5QQqV2m5
46
- hIPfLqCyxsn/YgOGvo6iwyQTWyTswamaAC3HRWZxIS1sfn/Ssqa7E7oQMkv5FAXr
47
- x5rKePfXINf8XTJczkl9OBEYdE9aNdJsJpXD0asLgGVwBICS5Bjohp6mizJcDC1+
48
- yZ0=
49
- -----END CERTIFICATE-----
50
-
51
- post_install_message:
28
+ post_install_message: |+
29
+
30
+ Thanks for installing Bleak House 3.1.
31
+
32
+ For each Rails app you want to profile, you will need to add the following
33
+ rake task in RAILS_ROOT/lib/tasks/bleak_house_tasks.rake to be able to run
34
+ the analyzer:
35
+
36
+ namespace :bleak_house do
37
+ desc 'Analyze and chart all data'
38
+ task :analyze do
39
+ require 'bleak_house/analyze'
40
+ BleakHouse::Analyze.build_all("#{RAILS_ROOT}/log/bleak_house_#{RAILS_ENV}.dump")
41
+ end
42
+ end
43
+
44
+
52
45
  authors:
53
46
  - Evan Weaver
54
47
  files:
55
- - TODO
56
- - test/unit/test_bleak_house.rb
57
- - test/misc/direct.rb
58
- - README
59
- - Rakefile
60
- - patches/parse.y.patch
61
- - patches/gc.c.patch
62
- - Manifest
63
- - LICENSE_RUBY
64
- - LICENSE_BSD
65
- - LICENSE
66
- - lib/vendor/lightcsv.rb
67
- - lib/bleak_house.rb
68
- - lib/bleak_house/support/rake.rb
69
- - lib/bleak_house/support/core_extensions.rb
70
- - lib/bleak_house/rails.rb
71
- - lib/bleak_house/rails/dispatcher.rb
72
- - lib/bleak_house/rails/bleak_house.rb
73
- - lib/bleak_house/rails/action_controller.rb
74
- - lib/bleak_house/logger.rb
75
- - lib/bleak_house/logger/mem_usage.rb
76
- - lib/bleak_house/analyzer.rb
77
- - lib/bleak_house/analyzer/analyzer.rb
78
- - install.rb
79
- - init.rb
80
- - ext/bleak_house/logger/snapshot.h
81
- - ext/bleak_house/logger/snapshot.c
82
- - ext/bleak_house/logger/extconf.rb
83
- - CHANGELOG
84
- - bin/bleak
85
- test_files:
86
- - test/unit/test_bleak_house.rb
48
+ - ./CHANGELOG
49
+ - ./LICENSE
50
+ - ./Manifest
51
+ - ./README
52
+ - ./Rakefile
53
+ - ./init.rb
54
+ - ./install.rb
55
+ - ./lib/bleak_house
56
+ - ./lib/bleak_house/action_controller.rb
57
+ - ./lib/bleak_house/analyze.rb
58
+ - ./lib/bleak_house/bleak_house.rb
59
+ - ./lib/bleak_house/dispatcher.rb
60
+ - ./lib/bleak_house/gruff_hacks.rb
61
+ - ./lib/bleak_house/mem_logger.rb
62
+ - ./lib/bleak_house/rake_task_redefine_task.rb
63
+ - ./lib/bleak_house/support_methods.rb
64
+ - ./lib/bleak_house.rb
65
+ - ./tasks/bleak_house_tasks.rake
66
+ test_files: []
67
+
87
68
  rdoc_options: []
88
69
 
89
70
  extra_rdoc_files: []
90
71
 
91
- executables:
92
- - bleak
93
- extensions:
94
- - ext/bleak_house/logger/extconf.rb
72
+ executables: []
73
+
74
+ extensions: []
75
+
95
76
  requirements: []
96
77
 
97
- dependencies:
98
- - !ruby/object:Gem::Dependency
99
- name: rake
100
- version_requirement:
101
- version_requirements: !ruby/object:Gem::Version::Requirement
102
- requirements:
103
- - - ">"
104
- - !ruby/object:Gem::Version
105
- version: 0.0.0
106
- version:
78
+ dependencies: []
79
+
data/LICENSE_BSD DELETED
@@ -1,10 +0,0 @@
1
-
2
- Copyright 2006, Eric Hodel. All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
-
6
- 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
- 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
- 3. Neither the names of the authors nor the names of their contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9
-
10
- THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS?? AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/LICENSE_RUBY DELETED
@@ -1,53 +0,0 @@
1
- $BK\%W%m%0%i%`$O%U%j!<%=%U%H%&%'%"$G$9!%(BGPL(the GNU General
2
- Public License)$B$^$?$O0J2<$K<($9>r7o$GK\%W%m%0%i%`$r:FG[I[$G(B
3
- $B$-$^$9!%(BGPL$B$K$D$$$F$O(BCOPYING.txt$B%U%!%$%k$r;2>H$7$F2<$5$$!%(B
4
-
5
- 1. $BJ#@=$O@)8B$J$/<+M3$G$9!%(B
6
-
7
- 2. $B0J2<$N>r7o$N$$$:$l$+$rK~$?$9;~$KK\%W%m%0%i%`$N%=!<%9$r(B
8
- $B<+M3$KJQ99$G$-$^$9!%(B
9
-
10
- (a) $B%M%C%H%K%e!<%:$K%]%9%H$7$?$j!$:n<T$KJQ99$rAwIU$9$k(B
11
- $B$J$I$NJ}K!$G!$JQ99$r8x3+$9$k!%(B
12
-
13
- (b) $BJQ99$7$?K\%W%m%0%i%`$r<+J,$N=jB0$9$kAH?%FbIt$@$1$G(B
14
- $B;H$&!%(B
15
-
16
- (c) $BJQ99E@$rL@<($7$?$&$(!$%=%U%H%&%'%"$NL>A0$rJQ99$9$k!%(B
17
- $B$=$N%=%U%H%&%'%"$rG[I[$9$k;~$K$OJQ99A0$NK\%W%m%0%i(B
18
- $B%`$bF1;~$KG[I[$9$k!%$^$?$OJQ99A0$NK\%W%m%0%i%`$N%=!<(B
19
- $B%9$NF~<jK!$rL@<($9$k!%(B
20
-
21
- (d) $B$=$NB>$NJQ99>r7o$r:n<T$H9g0U$9$k!%(B
22
-
23
- 3. $B0J2<$N>r7o$N$$$:$l$+$rK~$?$9;~$KK\%W%m%0%i%`$r%3%s%Q%$(B
24
- $B%k$7$?%*%V%8%'%/%H%3!<%I$d<B9T7A<0$G$bG[I[$G$-$^$9!%(B
25
-
26
- (a) $B%P%$%J%j$r<u$1<h$C$??M$,%=!<%9$rF~<j$G$-$k$h$&$K!$(B
27
- $B%=!<%9$NF~<jK!$rL@<($9$k!%(B
28
-
29
- (b) $B5!3#2DFI$J%=!<%9%3!<%I$rE:IU$9$k!%(B
30
-
31
- (c) $BJQ99$r9T$C$?%P%$%J%j$OL>A0$rJQ99$7$?$&$(!$%*%j%8%J(B
32
- $B%k$N%=!<%9%3!<%I$NF~<jK!$rL@<($9$k!%(B
33
-
34
- (d) $B$=$NB>$NG[I[>r7o$r:n<T$H9g0U$9$k!%(B
35
-
36
- 4. $BB>$N%W%m%0%i%`$X$N0zMQ$O$$$+$J$kL\E*$G$"$l<+M3$G$9!%$?(B
37
- $B$@$7!$K\%W%m%0%i%`$K4^$^$l$kB>$N:n<T$K$h$k%3!<%I$O!$$=(B
38
- $B$l$>$l$N:n<T$N0U8~$K$h$k@)8B$,2C$($i$k>l9g$,$"$j$^$9!%(B
39
-
40
- $B6qBNE*$K$O(Bgc.c($B0lIt(B)$B!$(Butil.c($B0lIt(B)$B!$(Bst.[ch]$B!$(Bregex.[ch]
41
- $B$*$h$S(B ./missing$B%G%#%l%/%H%j2<$N%U%!%$%k72$,3:Ev$7$^$9!%(B
42
- $B$=$l$>$l$NG[I[>r7o$J$I$KIU$$$F$O3F%U%!%$%k$r;2>H$7$F$/(B
43
- $B$@$5$$!%(B
44
-
45
- 5. $BK\%W%m%0%i%`$X$NF~NO$H$J$k%9%/%j%W%H$*$h$S!$K\%W%m%0%i(B
46
- $B%`$+$i$N=PNO$N8"Mx$OK\%W%m%0%i%`$N:n<T$G$O$J$/!$$=$l$>(B
47
- $B$l$NF~=PNO$r@8@.$7$??M$KB0$7$^$9!%$^$?!$K\%W%m%0%i%`$K(B
48
- $BAH$_9~$^$l$k$?$a$N3HD%%i%$%V%i%j$K$D$$$F$bF1MM$G$9!%(B
49
-
50
- 6. $BK\%W%m%0%i%`$OL5J]>Z$G$9!%:n<T$OK\%W%m%0%i%`$r%5%]!<%H(B
51
- $B$9$k0U;V$O$"$j$^$9$,!$%W%m%0%i%`<+?H$N%P%0$"$k$$$OK\%W(B
52
- $B%m%0%i%`$N<B9T$J$I$+$iH/@8$9$k$$$+$J$kB;32$KBP$7$F$b@U(B
53
- $BG$$r;}$A$^$;$s!%(B
data/TODO DELETED
@@ -1,2 +0,0 @@
1
-
2
- * Per-object memory usage. This may be impossible to do accurately.
data/bin/bleak DELETED
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- unless ARGV[0]
4
- puts "Please specify a BleakHouse logfile"
5
- exit
6
- else
7
- $LOAD_PATH << "#{File.dirname(__FILE__)}/../lib/"
8
- require 'bleak_house/analyzer'
9
- BleakHouse::Analyzer.run(ARGV[0])
10
- end
@@ -1,4 +0,0 @@
1
-
2
- require 'mkmf'
3
- dir_config('snapshot')
4
- create_makefile('bleak_house/logger/snapshot')
@@ -1,153 +0,0 @@
1
-
2
- #include "snapshot.h"
3
-
4
- static VALUE rb_mBleakHouse;
5
- static VALUE rb_cC;
6
-
7
- /* Number of struct heaps_slots used */
8
- static VALUE heaps_used(VALUE self) {
9
- return INT2FIX(rb_gc_heaps_used());
10
- }
11
-
12
- /* Length of the struct heaps_slots allocated */
13
- static VALUE heaps_length(VALUE self) {
14
- return INT2FIX(rb_gc_heaps_length());
15
- }
16
-
17
- /* Count the live objects on the heap and in the symbol table and write a CSV frame to <tt>_logfile</tt>. Set <tt>_specials = true</tt> if you also want to count AST nodes and var scopes; otherwise, use <tt>false</tt>. Note that common classes in the CSV output are hashed to small integers in order to save space.*/
18
- static VALUE snapshot(VALUE self, VALUE _logfile, VALUE tag, VALUE _specials) {
19
- Check_Type(_logfile, T_STRING);
20
- Check_Type(tag, T_STRING);
21
-
22
- RVALUE *obj, *obj_end;
23
- st_table_entry *sym, *sym_end;
24
-
25
- struct heaps_slot * heaps = rb_gc_heap_slots();
26
- struct st_table * sym_tbl = rb_parse_sym_tbl();
27
-
28
- int specials = RTEST(_specials);
29
- int hashed;
30
-
31
- /* see if the logfile exists already */
32
- FILE *logfile = fopen(StringValueCStr(_logfile), "r");
33
- int is_new;
34
- if (!(is_new = (logfile == NULL)))
35
- fclose(logfile);
36
-
37
- /* reopen for writing */
38
- if ((logfile = fopen(StringValueCStr(_logfile), "a+")) == NULL)
39
- rb_raise(rb_eRuntimeError, "couldn't open snapshot file");
40
-
41
- /* write the time */
42
- fprintf(logfile, "-1,%i\n", time(0));
43
-
44
- /* get and write the memory usage */
45
- VALUE mem = rb_funcall(self, rb_intern("mem_usage"), 0);
46
- fprintf(logfile, "-2,%i\n", NUM2INT(RARRAY_PTR(mem)[0]));
47
- fprintf(logfile, "-3,%i\n", NUM2INT(RARRAY_PTR(mem)[1]));
48
-
49
- int current_pos = 0;
50
- int filled_slots = 0;
51
- int free_slots = 0;
52
-
53
- /* write the tag header */
54
- fprintf(logfile, "-4,%s\n", StringValueCStr(tag));
55
-
56
- int i, j;
57
-
58
- /* walk the heap */
59
- for (i = 0; i < rb_gc_heaps_used(); i++) {
60
- obj = heaps[i].slot;
61
- obj_end = obj + heaps[i].limit;
62
- for (; obj < obj_end; obj++) {
63
- if (obj->as.basic.flags) { /* always 0 for freed objects */
64
- filled_slots ++;
65
- switch (TYPE(obj)) {
66
- case T_NONE:
67
- hashed = BUILTINS_SIZE + 0; break;
68
- case T_BLKTAG:
69
- hashed = BUILTINS_SIZE + 1; break;
70
- case T_UNDEF:
71
- hashed = BUILTINS_SIZE + 2; break;
72
- case T_VARMAP:
73
- hashed = BUILTINS_SIZE + 3; break;
74
- case T_SCOPE:
75
- hashed = BUILTINS_SIZE + 4; break;
76
- case T_NODE:
77
- hashed = BUILTINS_SIZE + 5; break;
78
- default:
79
- if (!obj->as.basic.klass) {
80
- hashed = BUILTINS_SIZE + 6;
81
- } else {
82
- hashed = lookup_builtin(rb_obj_classname((VALUE)obj));
83
- }
84
- }
85
- /* write to log */
86
- if (hashed < 0) {
87
- /* regular classname */
88
- fprintf(logfile, "%s,%lu\n", rb_obj_classname((VALUE)obj), FIX2ULONG(rb_obj_id((VALUE)obj)));
89
- } else {
90
- /* builtins key */
91
- if (specials || hashed < BUILTINS_SIZE) {
92
- /* 0 is not used for 'hashed' because Ruby's to_i turns any String into 0 */
93
- fprintf(logfile, "%i,%lu\n", hashed + 1, FIX2ULONG(rb_obj_id((VALUE)obj)));
94
- }
95
- }
96
- } else {
97
- free_slots ++;
98
- }
99
- }
100
- }
101
-
102
- /* walk the symbol table */
103
- hashed = lookup_builtin("Symbol");
104
- for (i = 0; i < sym_tbl->num_bins; i++) {
105
- for (sym = sym_tbl->bins[i]; sym != 0; sym = sym->next) {
106
- fprintf(logfile, "%i,%lu\n", hashed + 1, sym->record);
107
- }
108
- }
109
-
110
- fprintf(logfile, "-5,%i\n", filled_slots);
111
- fprintf(logfile, "-6,%i\n", free_slots);
112
- fclose(logfile);
113
-
114
- rb_funcall(rb_mGC, rb_intern("start"), 0); /* request GC run */
115
- return Qtrue;
116
- }
117
-
118
- int lookup_builtin(char * name) {
119
- int i;
120
- for (i = 0; i < BUILTINS_SIZE; i++) {
121
- if (!strcmp(builtins[i], name)) return i;
122
- }
123
- return -1;
124
- }
125
-
126
- /*
127
-
128
- This class performs the actual object logging of BleakHouse. To use it directly, you need to make calls to BleakHouse::Logger#snapshot.
129
-
130
- == Example
131
-
132
- At the start of your app, put:
133
- require 'rubygems'
134
- require 'bleak_house'
135
- $memlogger = BleakHouse::Logger.new
136
- File.delete($logfile = "/path/to/logfile") rescue nil
137
-
138
- Now, at the points of interest, put:
139
- $memlogger.snapshot($logfile, "tag/subtag", false)
140
-
141
- Run your app. Once you are done, analyze your data:
142
- bleak /path/to/logfile
143
-
144
- */
145
- void
146
- Init_snapshot()
147
- {
148
- rb_mBleakHouse = rb_define_module("BleakHouse");
149
- rb_cC = rb_define_class_under(rb_mBleakHouse, "Logger", rb_cObject);
150
- rb_define_method(rb_cC, "snapshot", snapshot, 3);
151
- rb_define_method(rb_cC, "heaps_used", heaps_used, 0);
152
- rb_define_method(rb_cC, "heaps_length", heaps_length, 0);
153
- }
@@ -1,99 +0,0 @@
1
- #include "ruby.h"
2
- #include "env.h"
3
- #include "node.h"
4
- #include "st.h"
5
- #include "re.h"
6
- #include "util.h"
7
- #include "intern.h"
8
- #include "string.h"
9
-
10
- /* Histogram of most common Rails classes */
11
- static char * builtins[] = {
12
- "String",
13
- "Array",
14
- "Hash",
15
- "Class",
16
- "Regexp",
17
- "Proc",
18
- "ActionController::Routing::DividerSegment",
19
- "Gem::Version",
20
- "Gem::Version::Requirement",
21
- "Bignum",
22
- "Symbol",
23
- "Time",
24
- "MatchData",
25
- "Gem::Specification",
26
- "ActionController::Routing::StaticSegment",
27
- "Gem::Dependency",
28
- "Module",
29
- "ActionController::Routing::DynamicSegment",
30
- "Range",
31
- "ActionController::Routing::Route",
32
- "Float",
33
- "HashWithIndifferentAccess",
34
- "Method",
35
- "Enumerable",
36
- "Comparable",
37
- "Set",
38
- "File",
39
- "Object",
40
- "NameError",
41
- "Thread",
42
- "_node",
43
- "_none",
44
- "_blktag",
45
- "_undef",
46
- "_varmap",
47
- "_scope",
48
- "_unknown"
49
- };
50
-
51
- #define BUILTINS_SIZE 30
52
- #define SPECIALS_SIZE 7
53
-
54
- typedef struct RVALUE {
55
- union {
56
- struct {
57
- unsigned long flags; /* always 0 for freed obj */
58
- struct RVALUE *next;
59
- } free;
60
- struct RBasic basic;
61
- struct RObject object;
62
- struct RClass klass;
63
- struct RFloat flonum;
64
- struct RString string;
65
- struct RArray array;
66
- struct RRegexp regexp;
67
- struct RHash hash;
68
- struct RData data;
69
- struct RStruct rstruct;
70
- struct RBignum bignum;
71
- struct RFile file;
72
- struct RNode node;
73
- struct RMatch match;
74
- struct RVarmap varmap;
75
- struct SCOPE scope;
76
- } as;
77
- } RVALUE;
78
-
79
- struct heaps_slot {
80
- void *membase;
81
- RVALUE *slot;
82
- int limit;
83
- };
84
-
85
- typedef struct st_table_entry st_table_entry;
86
-
87
- struct st_table_entry {
88
- unsigned int hash;
89
- st_data_t key;
90
- st_data_t record;
91
- st_table_entry *next;
92
- };
93
-
94
- struct st_table * rb_parse_sym_tbl();
95
- struct heaps_slot * rb_gc_heap_slots();
96
- int rb_gc_heaps_used();
97
- int rb_gc_heaps_length();
98
-
99
- int lookup_builtin(char *);
@@ -1,143 +0,0 @@
1
-
2
- require 'rubygems'
3
- require 'fileutils'
4
- require 'yaml'
5
- require 'pp'
6
- require 'ruby-debug'
7
-
8
- module BleakHouse
9
-
10
- class Analyzer
11
-
12
- MAGIC_KEYS = {
13
- -1 => 'timestamp',
14
- -2 => 'mem usage/swap',
15
- -3 => 'mem usage/real',
16
- -4 => 'tag',
17
- -5 => 'heap/filled',
18
- -6 => 'heap/free'
19
- }
20
-
21
- CLASS_KEYS = eval('[nil, ' + # skip 0
22
- open(
23
- File.dirname(__FILE__) + '/../../../ext/bleak_house/logger/snapshot.h'
24
- ).read[/\{(.*?)\}/m, 1] + ']')
25
-
26
- # Parses and correlates a BleakHouse::Logger output file.
27
- def self.run(logfile)
28
- unless File.exists? logfile
29
- puts "No data file found: #{logfile}"
30
- exit
31
- end
32
-
33
- frames = []
34
- last_population = []
35
- frame = nil
36
- ix = nil
37
-
38
- puts "Examining objects"
39
-
40
- LightCsv.foreach(logfile) do |row|
41
-
42
- # Stupid is fast
43
- row[0] = row[0].to_i if row[0].to_i != 0
44
- row[1] = row[1].to_i if row[1].to_i != 0
45
-
46
- if row[0].to_i < 0
47
- # Get frame meta-information
48
- if MAGIC_KEYS[row[0]] == 'timestamp'
49
-
50
- # The frame has ended; process the last one
51
- if frame
52
- population = frame['objects'].keys
53
- births = population - last_population
54
- deaths = last_population - population
55
- last_population = population
56
-
57
- # assign births
58
- frame['births'] = frame['objects'].slice(births)
59
-
60
- if final = frames[-2]
61
- final['deaths'] = final['objects'].slice(deaths)
62
- bsize = final['births'].size
63
- dsize = final['deaths'].size
64
- final['velocity'] = bsize * 100 / dsize / 100.0
65
- puts " Frame #{frames.size - 1} (#{final['meta']['tag]}) finalized: #{bsize} births, #{dsize} deaths, velocity #{final['velocity']}, population #{final['objects'].size}"
66
- final.delete 'objects'
67
- end
68
- end
69
-
70
- # Set up a new frame
71
- frame = {}
72
- frames << frame
73
- frame['objects'] ||= {}
74
- frame['meta'] ||= {}
75
-
76
- #puts " Frame #{frames.size} opened"
77
- end
78
-
79
- frame['meta'][MAGIC_KEYS[row[0]]] = row[1]
80
- else
81
- # Assign live objects
82
- frame['objects'][row[1]] = row[0]
83
- end
84
- end
85
-
86
- # See what objects are still laying around
87
- population = frames.last['objects'].reject do |key, value|
88
- frames.first['births'][key] == value
89
- end
90
-
91
- # Remove bogus frames
92
- frames = frames[1..-3]
93
-
94
- total_births = frames.inject(0) do |births, frame|
95
- births + frame['births'].size
96
- end
97
- total_deaths = frames.inject(0) do |deaths, frame|
98
- deaths + frame['deaths'].size
99
- end
100
-
101
- puts "#{total_births} total meaningful births, #{total_deaths} total meaningful deaths.\n\n"
102
-
103
- leakers = {}
104
-
105
- # Find the sources of the leftover objects in the final population
106
- population.each do |id, klass|
107
- leaker = frames.detect do |frame|
108
- frame['births'][id] == klass
109
- end
110
- if leaker
111
- tag = leaker['meta']['tag']
112
- klass = CLASS_KEYS[klass] if klass.is_a? Fixnum
113
- leakers[tag] ||= Hash.new(0)
114
- leakers[tag][klass] += 1
115
- end
116
- end
117
-
118
- # Sort
119
- leakers = leakers.map do |tag, value|
120
- [tag, value.sort_by do |klass, count|
121
- -count
122
- end]
123
- end.sort_by do |tag, value|
124
- Hash[*value.flatten].values.inject(0) {|i, v| i - v}
125
- end
126
-
127
- puts "Here are your leaks:"
128
- leakers.each do |tag, value|
129
- puts " #{tag} leaked per request:"
130
- requests = frames.select do |frame|
131
- frame['meta']['tag'] == tag
132
- end.size
133
- value.each do |klass, count|
134
- count = count/requests
135
- puts " #{count} #{klass}" if count > 0
136
- end
137
- end
138
- puts "\nBye"
139
-
140
- end
141
-
142
- end
143
- end
@@ -1,5 +0,0 @@
1
-
2
- require 'vendor/lightcsv'
3
-
4
- require 'bleak_house/support/core_extensions'
5
- require 'bleak_house/analyzer/analyzer'
@@ -1,13 +0,0 @@
1
-
2
- module BleakHouse
3
-
4
- class Logger
5
-
6
- # Returns an array of the running process's real and virtual memory usage, in kilobytes.
7
- def mem_usage
8
- a = `ps -o vsz,rss -p #{Process.pid}`.split(/\s+/)[-2..-1].map{|el| el.to_i}
9
- [a.first - a.last, a.last]
10
- end
11
-
12
- end
13
- end