allocation_tracer 0.3.2 → 0.3.3

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