allocation_tracer 0.3.2 → 0.3.3

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: 89fd66efaa24f2319186b9499095bad976c68bfe
4
- data.tar.gz: dff3b6ab0c8ba0a3db0a1140285dcdd9e06c569c
3
+ metadata.gz: 1a8521b2ac3ab75ead4770b8aa3b9982f8467d84
4
+ data.tar.gz: a4b23c68be89223a669d149cf08bd6105cbcaf7e
5
5
  SHA512:
6
- metadata.gz: 07a014504c663e8ff614ebeec62c49c2dcfb1cf30be1c3009cfa9da0c2d1f7a44ca8789db5919f1aeb6b337719fe0a6f614756749ac8c5aec0c91a766bb33085
7
- data.tar.gz: 96fcd0458afc5d052843b269693c9f1fbffaa2df341abca68b11fd8e28bab04464cb0202b85629c61d3f22ed93ade287c656f06c43ac6b3da8204553b89177fe
6
+ metadata.gz: 58e5ab416b474b20fedef2a0a99e39d0da0dde7074f50a28047e0205240aa4ae660e9c4df114acfcacf496d657d6cc660b8fbaf4353369c5d400b3b70ab14d78
7
+ data.tar.gz: c4176f951ee62200e6e4faace8b9c5e7d0240d8bf4217a868d120758eed8725ba007e059d7af62c7bfe1835a18b953a46cb7adf3db9b23863d4cc9a5ca336776
data/README.md CHANGED
@@ -30,10 +30,10 @@ Or install it yourself as:
30
30
 
31
31
  You can trace allocation and aggregate information. Information includes:
32
32
 
33
- count - how many objects are created.
34
- total_age - total age of objects which created here
35
- max_age - age of longest living object created here
36
- min_age - age of shortest living object created here
33
+ * count - how many objects are created.
34
+ * total_age - total age of objects which created here
35
+ * max_age - age of longest living object created here
36
+ * min_age - age of shortest living object created here
37
37
 
38
38
  Age of Object can be calculated by this formula: [current GC count] - [birth time GC count]
39
39
 
@@ -55,14 +55,17 @@ pp ObjectSpace::AllocationTracer.trace{
55
55
  will show
56
56
 
57
57
  ```
58
- {["test.rb", 6]=>[50000, 44290, 0, 6],
59
- ["test.rb", 7]=>[50000, 44289, 0, 5],
60
- ["test.rb", 8]=>[50000, 44295, 0, 6]}
58
+ {["test.rb", 6]=>[50000, 0, 47440, 0, 1, 0],
59
+ ["test.rb", 7]=>[50000, 4, 47452, 0, 6, 0],
60
+ ["test.rb", 8]=>[50000, 7, 47456, 0, 6, 0]}
61
61
  ```
62
62
 
63
- In this case, 50,000 objects are created at `test.rb:6'. 44,290 is total
64
- age of objects created at this line. Average age of object created at
65
- this line is 50000/44290 = 0.8858. 0 is minimum age and 6 is maximum age.
63
+ In this case,
64
+ * 50,000 objects are created at `test.rb:6' and
65
+ * 5 old objects created.
66
+ * 44,290 is total age of objects created at this line (average age of object created at this line is 50000/44290 = 0.8858).
67
+ * 0 is minimum age
68
+ * 6 is maximum age.
66
69
 
67
70
  You can also specify `type' in GC::Tracer.setup_allocation_tracing() to
68
71
  specify what should be keys to aggregate like that.
@@ -87,12 +90,12 @@ pp result
87
90
  and you will get:
88
91
 
89
92
  ```
90
- {["test.rb", 8, :T_STRING]=>[50000, 49067, 0, 17],
91
- ["test.rb", 8, :T_ARRAY]=>[50000, 49053, 0, 17],
92
- ["test.rb", 9, :T_STRING]=>[100000, 98146, 0, 17],
93
- ["test.rb", 9, :T_HASH]=>[50000, 49111, 0, 17],
94
- ["test.rb", 10, :T_STRING]=>[100000, 98267, 0, 17],
95
- ["test.rb", 10, :T_STRUCT]=>[50000, 49126, 0, 17]}
93
+ {["test.rb", 8, :T_STRING]=>[50000, 15, 49165, 0, 16, 0],
94
+ ["test.rb", 8, :T_ARRAY]=>[50000, 12, 49134, 0, 16, 0],
95
+ ["test.rb", 9, :T_STRING]=>[100000, 27, 98263, 0, 16, 0],
96
+ ["test.rb", 9, :T_HASH]=>[50000, 16, 49147, 0, 16, 8998848],
97
+ ["test.rb", 10, :T_STRING]=>[100000, 36, 98322, 0, 16, 0],
98
+ ["test.rb", 10, :T_STRUCT]=>[50000, 16, 49147, 0, 16, 0]}
96
99
  ```
97
100
 
98
101
  Interestingly, you can not see array creations in a middle of block:
@@ -116,7 +119,7 @@ pp result
116
119
  and it prints:
117
120
 
118
121
  ```
119
- {["test.rb", 8, :T_STRING]=>[50000, 38322, 0, 2]}
122
+ {["test.rb", 8, :T_STRING]=>[25015, 5, 16299, 0, 2, 0]}
120
123
  ```
121
124
 
122
125
  There are only string creation. This is because unused array creation is
@@ -140,13 +143,13 @@ require 'allocation_tracer/trace'
140
143
  and you will see:
141
144
 
142
145
  ```
143
- path line count total_age max_age min_age
144
- .../lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb 55 18 23 1 6
145
- .../lib/allocation_tracer/trace.rb 6 2 12 6 6
146
- test.rb 0 1 0 0 0
147
- test.rb 5 50000 41645 0 4
148
- test.rb 6 50000 41648 0 5
149
- test.rb 7 50000 41650 0 5
146
+ path line count old_count total_age min_age max_age total_memsize
147
+ ...rubygems/core_ext/kernel_require.rb 55 18 1 23 1 6 358
148
+ ...lib/allocation_tracer/lib/allocation_tracer/trace.rb 6 2 012 6 6 0
149
+ test.rb 0 1 0 0 0 0 0
150
+ test.rb 5 50000 4 41492 0 5 0
151
+ test.rb 6 50000 3 41490 0 5 0
152
+ test.rb 7 50000 7 41497 0 5 0
150
153
  ```
151
154
 
152
155
  (tab separated colums)
@@ -526,6 +526,7 @@ type_sym(int type)
526
526
  }
527
527
 
528
528
  struct arg_and_result {
529
+ int update;
529
530
  struct traceobj_arg *arg;
530
531
  VALUE result;
531
532
  };
@@ -536,14 +537,9 @@ aggregate_result_i(st_data_t key, st_data_t val, void *data)
536
537
  struct arg_and_result *aar = (struct arg_and_result *)data;
537
538
  struct traceobj_arg *arg = aar->arg;
538
539
  VALUE result = aar->result;
539
-
540
540
  size_t *val_buff = (size_t *)val;
541
541
  struct memcmp_key_data *key_buff = (struct memcmp_key_data *)key;
542
- VALUE v = rb_ary_new3(6,
543
- INT2FIX(val_buff[0]), INT2FIX(val_buff[1]),
544
- INT2FIX(val_buff[2]), INT2FIX(val_buff[3]),
545
- INT2FIX(val_buff[4]), INT2FIX(val_buff[5]));
546
- VALUE k = rb_ary_new();
542
+ VALUE v, oldv, k = rb_ary_new();
547
543
  int i = 0;
548
544
 
549
545
  i = 0;
@@ -577,6 +573,25 @@ aggregate_result_i(st_data_t key, st_data_t val, void *data)
577
573
  }
578
574
  }
579
575
 
576
+ #define MIN(a, b) ((a) < (b) ? (a) : (b))
577
+ #define MAX(a, b) ((a) > (b) ? (a) : (b))
578
+
579
+ if (aar->update && (oldv = rb_hash_aref(result, k)) != Qnil) {
580
+ v = rb_ary_new3(6,
581
+ INT2FIX(val_buff[0] + FIX2INT(RARRAY_AREF(oldv, 0))), /* count */
582
+ INT2FIX(val_buff[1] + FIX2INT(RARRAY_AREF(oldv, 1))), /* old count */
583
+ INT2FIX(val_buff[2] + FIX2INT(RARRAY_AREF(oldv, 2))), /* total_age */
584
+ INT2FIX(MIN(val_buff[3], FIX2INT(RARRAY_AREF(oldv, 3)))), /* min age */
585
+ INT2FIX(MAX(val_buff[4], FIX2INT(RARRAY_AREF(oldv, 4)))), /* max age */
586
+ INT2FIX(val_buff[5] + FIX2INT(RARRAY_AREF(oldv, 5)))); /* memsize_of */
587
+ }
588
+ else {
589
+ v = rb_ary_new3(6,
590
+ INT2FIX(val_buff[0]), INT2FIX(val_buff[1]),
591
+ INT2FIX(val_buff[2]), INT2FIX(val_buff[3]),
592
+ INT2FIX(val_buff[4]), INT2FIX(val_buff[5]));
593
+ }
594
+
580
595
  rb_hash_aset(result, k, v);
581
596
 
582
597
  return ST_CONTINUE;
@@ -627,6 +642,12 @@ lifetime_table_for_live_objects_i(st_data_t key, st_data_t val, st_data_t data)
627
642
  return ST_CONTINUE;
628
643
  }
629
644
 
645
+ static int
646
+ st_size(struct st_table *st)
647
+ {
648
+ return st->num_bins;
649
+ }
650
+
630
651
  static VALUE
631
652
  aggregate_result(struct traceobj_arg *arg)
632
653
  {
@@ -634,11 +655,14 @@ aggregate_result(struct traceobj_arg *arg)
634
655
  aar.result = rb_hash_new();
635
656
  aar.arg = arg;
636
657
 
637
- /* aggregated table -> Ruby hash */
638
- aggregate_freed_info(arg);
658
+ while (arg->freed_allocation_info) {
659
+ aggregate_freed_info(arg);
660
+ }
661
+
662
+ /* collect from recent-freed objects */
663
+ aar.update = 0;
639
664
  st_foreach(arg->aggregate_table, aggregate_result_i, (st_data_t)&aar);
640
665
 
641
- /* collect live aggregate table */
642
666
  {
643
667
  st_table *dead_object_aggregate_table = arg->aggregate_table;
644
668
 
@@ -647,6 +671,7 @@ aggregate_result(struct traceobj_arg *arg)
647
671
  st_foreach(arg->object_table, aggregate_live_object_i, (st_data_t)arg);
648
672
 
649
673
  /* aggregate table -> Ruby hash */
674
+ aar.update = 1;
650
675
  st_foreach(arg->aggregate_table, aggregate_result_i, (st_data_t)&aar);
651
676
 
652
677
  /* remove live object aggregate table */
@@ -1,3 +1,3 @@
1
1
  module ObjectSpace::AllocationTracer
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
@@ -2,6 +2,16 @@ require "allocation_tracer/version"
2
2
  require "allocation_tracer/allocation_tracer"
3
3
 
4
4
  module ObjectSpace::AllocationTracer
5
+
6
+ def self.output_lifetime_table table
7
+ out = (file = ENV['RUBY_ALLOCATION_TRACER_LIFETIME_OUT']) ? open(File.expand_path(file), 'w') : STDOUT
8
+ max_lines = table.inject(0){|r, (type, lines)| r < lines.size ? lines.size : r}
9
+ out.puts "type\t" + (0...max_lines).to_a.join("\t")
10
+ table.each{|type, line|
11
+ out.puts "#{type}\t#{line.join("\t")}"
12
+ }
13
+ end
14
+
5
15
  def self.collect_lifetime_talbe
6
16
  ObjectSpace::AllocationTracer.lifetime_table_setup true
7
17
 
@@ -10,7 +20,8 @@ module ObjectSpace::AllocationTracer
10
20
  ObjectSpace::AllocationTracer.trace do
11
21
  yield
12
22
  end
13
- ObjectSpace::AllocationTracer.lifetime_table
23
+ result = ObjectSpace::AllocationTracer.lifetime_table
24
+ output_lifetime_table(result)
14
25
  ensure
15
26
  ObjectSpace::AllocationTracer.lifetime_table_setup false
16
27
  end
@@ -23,6 +34,7 @@ module ObjectSpace::AllocationTracer
23
34
  ObjectSpace::AllocationTracer.stop
24
35
  result = ObjectSpace::AllocationTracer.lifetime_table
25
36
  ObjectSpace::AllocationTracer.lifetime_table_setup false
37
+ output_lifetime_table(result)
26
38
  result
27
39
  end
28
40
  end
@@ -25,6 +25,23 @@ describe ObjectSpace::AllocationTracer do
25
25
  expect(result[[__FILE__, line]]).to eq [1, 0, 0, 0, 0, 0]
26
26
  end
27
27
 
28
+ it 'should analyze many objects' do
29
+ line = __LINE__ + 3
30
+ result = ObjectSpace::AllocationTracer.trace do
31
+ 50_000.times{|i|
32
+ i.to_s
33
+ i.to_s
34
+ i.to_s
35
+ }
36
+ end
37
+ #GC.start
38
+ #pp result
39
+
40
+ expect(result[[__FILE__, line + 0]][0]).to be >= 50_000
41
+ expect(result[[__FILE__, line + 1]][0]).to be >= 50_000
42
+ expect(result[[__FILE__, line + 2]][0]).to be >= 50_000
43
+ end
44
+
28
45
  it 'should count old objects' do
29
46
  a = nil
30
47
  line = __LINE__ + 2
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allocation_tracer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Sasada
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-23 00:00:00.000000000 Z
11
+ date: 2014-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler