allocation_tracer 0.2.0 → 0.3.0
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 +4 -4
- data/README.md +34 -0
- data/ext/allocation_tracer/allocation_tracer.c +213 -72
- data/lib/allocation_tracer/version.rb +1 -1
- data/spec/allocation_tracer_spec.rb +39 -0
- metadata +2 -3
- data/lib/allocation_tracer/allocation_tracer.so +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e21df296d813762ba6a5b3393ae95cbc09fa2560
|
4
|
+
data.tar.gz: 089e3fcaa7df385f58c91a3762d1c1f714cbb50a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9f98fcbbd4a1e7cac48aaab69e10e9857b63050ffb8ec7e9d8ef9800d9668cfb2715ec2414ed277276edaf3ca53527f1606ec589656b71ea972d33d4a3d8765
|
7
|
+
data.tar.gz: 7d34cd7d37a60411664a82b94edb9b832cbe00a351c5b9b4da33adce9ee354b98f3f79d99ab594b6253675c1ffe4c6e3a3487052f4e7f7ba9ad586e823ff2f7d
|
data/README.md
CHANGED
@@ -151,6 +151,40 @@ test.rb 7 50000 41650 0 5
|
|
151
151
|
|
152
152
|
(tab separated colums)
|
153
153
|
|
154
|
+
### Lifetime table
|
155
|
+
|
156
|
+
You can collect lifetime statistics with
|
157
|
+
ObjectSpace::AllocationTracer.lifetime_table method.
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
require 'pp'
|
161
|
+
require 'allocation_tracer'
|
162
|
+
|
163
|
+
ObjectSpace::AllocationTracer.lifetime_table_setup true
|
164
|
+
result = ObjectSpace::AllocationTracer.trace do
|
165
|
+
100000.times{
|
166
|
+
Object.new
|
167
|
+
''
|
168
|
+
}
|
169
|
+
end
|
170
|
+
pp ObjectSpace::AllocationTracer.lifetime_table
|
171
|
+
```
|
172
|
+
|
173
|
+
will show
|
174
|
+
|
175
|
+
```
|
176
|
+
{:T_OBJECT=>[3434, 96563, 0, 0, 1, 0, 0, 2],
|
177
|
+
:T_STRING=>[3435, 96556, 2, 1, 1, 1, 1, 1, 2]}
|
178
|
+
```
|
179
|
+
|
180
|
+
This output means that the age of 3434 T_OBJECT objects are 0, 96563
|
181
|
+
objects are 1 and 2 objects are 7. Also the age of 3435 T_STRING
|
182
|
+
objects are 0, 96556 are 1 and so on.
|
183
|
+
|
184
|
+
Note that these number includes living objects and dead objects. For
|
185
|
+
dead object, age means lifetime. For living objects, age means current
|
186
|
+
age.
|
187
|
+
|
154
188
|
## Contributing
|
155
189
|
|
156
190
|
1. Fork it ( http://github.com/<my-github-username>/allocation_tracer/fork )
|
@@ -13,6 +13,19 @@ size_t rb_obj_memsize_of(VALUE obj); /* in gc.c */
|
|
13
13
|
|
14
14
|
static VALUE rb_mAllocationTracer;
|
15
15
|
|
16
|
+
struct traceobj_arg {
|
17
|
+
int running;
|
18
|
+
int keys, vals;
|
19
|
+
st_table *object_table; /* obj (VALUE) -> allocation_info */
|
20
|
+
st_table *str_table; /* cstr -> refcount */
|
21
|
+
|
22
|
+
st_table *aggregate_table; /* user defined key -> [count, total_age, max_age, min_age] */
|
23
|
+
struct allocation_info *freed_allocation_info;
|
24
|
+
|
25
|
+
/* */
|
26
|
+
size_t **lifetime_table;
|
27
|
+
};
|
28
|
+
|
16
29
|
struct allocation_info {
|
17
30
|
struct allocation_info *next;
|
18
31
|
|
@@ -44,15 +57,6 @@ struct allocation_info {
|
|
44
57
|
#define VAL_MAX_AGE (1<<5)
|
45
58
|
#define VAL_MEMSIZE (1<<6)
|
46
59
|
|
47
|
-
struct traceobj_arg {
|
48
|
-
int running;
|
49
|
-
int keys, vals;
|
50
|
-
st_table *aggregate_table; /* user defined key -> [count, total_age, max_age, min_age] */
|
51
|
-
st_table *object_table; /* obj (VALUE) -> allocation_info */
|
52
|
-
st_table *str_table; /* cstr -> refcount */
|
53
|
-
struct allocation_info *freed_allocation_info;
|
54
|
-
};
|
55
|
-
|
56
60
|
static char *
|
57
61
|
keep_unique_str(st_table *tbl, const char *str)
|
58
62
|
{
|
@@ -145,6 +149,7 @@ get_traceobj_arg(void)
|
|
145
149
|
tmp_trace_arg->object_table = st_init_numtable();
|
146
150
|
tmp_trace_arg->str_table = st_init_strtable();
|
147
151
|
tmp_trace_arg->freed_allocation_info = NULL;
|
152
|
+
tmp_trace_arg->lifetime_table = NULL;
|
148
153
|
}
|
149
154
|
return tmp_trace_arg;
|
150
155
|
}
|
@@ -182,6 +187,17 @@ clear_traceobj_arg(void)
|
|
182
187
|
st_clear(arg->object_table);
|
183
188
|
st_foreach(arg->str_table, free_keys_i, 0);
|
184
189
|
st_clear(arg->str_table);
|
190
|
+
|
191
|
+
if (arg->lifetime_table) {
|
192
|
+
int i;
|
193
|
+
|
194
|
+
for (i=0; i<T_MASK; i++) {
|
195
|
+
if (arg->lifetime_table[i] != NULL) {
|
196
|
+
free(arg->lifetime_table[i]);
|
197
|
+
arg->lifetime_table[i] = NULL;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
}
|
185
201
|
}
|
186
202
|
|
187
203
|
static struct allocation_info *
|
@@ -261,7 +277,7 @@ aggregate_each_info(struct traceobj_arg *arg, struct allocation_info *info, size
|
|
261
277
|
key = (st_data_t)&key_data;
|
262
278
|
|
263
279
|
if (st_lookup(arg->aggregate_table, key, &val) == 0) {
|
264
|
-
struct memcmp_key_data *key_buff = ruby_xmalloc(sizeof(
|
280
|
+
struct memcmp_key_data *key_buff = ruby_xmalloc(sizeof(struct memcmp_key_data));
|
265
281
|
key_buff->n = key_data.n;
|
266
282
|
|
267
283
|
for (i=0; i<key_data.n; i++) {
|
@@ -315,6 +331,34 @@ move_to_freed_list(struct traceobj_arg *arg, struct allocation_info *info)
|
|
315
331
|
arg->freed_allocation_info = info;
|
316
332
|
}
|
317
333
|
|
334
|
+
static void
|
335
|
+
add_lifetime_table(size_t **lines, int type, struct allocation_info *info)
|
336
|
+
{
|
337
|
+
size_t age = rb_gc_count() - info->generation;
|
338
|
+
size_t *line = lines[type];
|
339
|
+
size_t len, i;
|
340
|
+
|
341
|
+
if (line == NULL) {
|
342
|
+
len = age + 1;
|
343
|
+
line = lines[type] = malloc(sizeof(size_t) * (1 + len));
|
344
|
+
line[0] = len;
|
345
|
+
for (i=0; i<len; i++) line[i+1] = 0;
|
346
|
+
}
|
347
|
+
else {
|
348
|
+
len = line[0];
|
349
|
+
|
350
|
+
if (len < age + 1) {
|
351
|
+
size_t old_len = len;
|
352
|
+
len = age + 1;
|
353
|
+
line = lines[type] = realloc(line, sizeof(size_t) * (1 + len));
|
354
|
+
for (i=old_len; i<len; i++) line[i+1] = 0;
|
355
|
+
line[0] = len;
|
356
|
+
}
|
357
|
+
}
|
358
|
+
|
359
|
+
line[age + 1]++;
|
360
|
+
}
|
361
|
+
|
318
362
|
static void
|
319
363
|
freeobj_i(VALUE tpval, void *data)
|
320
364
|
{
|
@@ -331,6 +375,20 @@ freeobj_i(VALUE tpval, void *data)
|
|
331
375
|
if (arg->freed_allocation_info == NULL) {
|
332
376
|
rb_postponed_job_register_one(0, aggregate_freed_info, arg);
|
333
377
|
}
|
378
|
+
|
379
|
+
if (arg->lifetime_table) {
|
380
|
+
add_lifetime_table(arg->lifetime_table, BUILTIN_TYPE(obj), info);
|
381
|
+
}
|
382
|
+
}
|
383
|
+
}
|
384
|
+
|
385
|
+
static void
|
386
|
+
check_tracer_running(void)
|
387
|
+
{
|
388
|
+
struct traceobj_arg * arg = get_traceobj_arg();
|
389
|
+
|
390
|
+
if (!arg->running) {
|
391
|
+
rb_raise(rb_eRuntimeError, "not started yet");
|
334
392
|
}
|
335
393
|
}
|
336
394
|
|
@@ -339,6 +397,8 @@ enable_newobj_hook(void)
|
|
339
397
|
{
|
340
398
|
VALUE newobj_hook;
|
341
399
|
|
400
|
+
check_tracer_running();
|
401
|
+
|
342
402
|
if ((newobj_hook = rb_ivar_get(rb_mAllocationTracer, rb_intern("newobj_hook"))) == Qnil) {
|
343
403
|
rb_raise(rb_eRuntimeError, "not started.");
|
344
404
|
}
|
@@ -354,6 +414,8 @@ disable_newobj_hook(void)
|
|
354
414
|
{
|
355
415
|
VALUE newobj_hook;
|
356
416
|
|
417
|
+
check_tracer_running();
|
418
|
+
|
357
419
|
if ((newobj_hook = rb_ivar_get(rb_mAllocationTracer, rb_intern("newobj_hook"))) == Qnil) {
|
358
420
|
rb_raise(rb_eRuntimeError, "not started.");
|
359
421
|
}
|
@@ -364,16 +426,6 @@ disable_newobj_hook(void)
|
|
364
426
|
rb_tracepoint_disable(newobj_hook);
|
365
427
|
}
|
366
428
|
|
367
|
-
static void
|
368
|
-
check_tracer_running(void)
|
369
|
-
{
|
370
|
-
struct traceobj_arg * arg = get_traceobj_arg();
|
371
|
-
|
372
|
-
if (!arg->running) {
|
373
|
-
rb_raise(rb_eRuntimeError, "not started yet");
|
374
|
-
}
|
375
|
-
}
|
376
|
-
|
377
429
|
static void
|
378
430
|
start_alloc_hooks(VALUE mod)
|
379
431
|
{
|
@@ -412,39 +464,49 @@ stop_alloc_hooks(VALUE self)
|
|
412
464
|
return Qnil;
|
413
465
|
}
|
414
466
|
|
415
|
-
static
|
416
|
-
|
417
|
-
{
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
467
|
+
static VALUE
|
468
|
+
type_sym(int type)
|
469
|
+
{
|
470
|
+
static VALUE syms[T_MASK];
|
471
|
+
|
472
|
+
if (syms[0] == 0) {
|
473
|
+
int i;
|
474
|
+
for (i=0; i<T_MASK; i++) {
|
475
|
+
switch (i) {
|
476
|
+
#define TYPE_NAME(t) case (t): syms[i] = ID2SYM(rb_intern(#t)); break;
|
477
|
+
TYPE_NAME(T_NONE);
|
478
|
+
TYPE_NAME(T_OBJECT);
|
479
|
+
TYPE_NAME(T_CLASS);
|
480
|
+
TYPE_NAME(T_MODULE);
|
481
|
+
TYPE_NAME(T_FLOAT);
|
482
|
+
TYPE_NAME(T_STRING);
|
483
|
+
TYPE_NAME(T_REGEXP);
|
484
|
+
TYPE_NAME(T_ARRAY);
|
485
|
+
TYPE_NAME(T_HASH);
|
486
|
+
TYPE_NAME(T_STRUCT);
|
487
|
+
TYPE_NAME(T_BIGNUM);
|
488
|
+
TYPE_NAME(T_FILE);
|
489
|
+
TYPE_NAME(T_MATCH);
|
490
|
+
TYPE_NAME(T_COMPLEX);
|
491
|
+
TYPE_NAME(T_RATIONAL);
|
492
|
+
TYPE_NAME(T_NIL);
|
493
|
+
TYPE_NAME(T_TRUE);
|
494
|
+
TYPE_NAME(T_FALSE);
|
495
|
+
TYPE_NAME(T_SYMBOL);
|
496
|
+
TYPE_NAME(T_FIXNUM);
|
497
|
+
TYPE_NAME(T_UNDEF);
|
498
|
+
TYPE_NAME(T_NODE);
|
499
|
+
TYPE_NAME(T_ICLASS);
|
500
|
+
TYPE_NAME(T_ZOMBIE);
|
501
|
+
TYPE_NAME(T_DATA);
|
502
|
+
default:
|
503
|
+
syms[i] = ID2SYM(rb_intern("unknown"));
|
445
504
|
#undef TYPE_NAME
|
505
|
+
}
|
506
|
+
}
|
446
507
|
}
|
447
|
-
|
508
|
+
|
509
|
+
return syms[type];
|
448
510
|
}
|
449
511
|
|
450
512
|
struct arg_and_result {
|
@@ -467,14 +529,6 @@ aggregate_result_i(st_data_t key, st_data_t val, void *data)
|
|
467
529
|
INT2FIX(val_buff[4]), INT2FIX(val_buff[5]));
|
468
530
|
VALUE k = rb_ary_new();
|
469
531
|
int i = 0;
|
470
|
-
static VALUE type_symbols[T_MASK] = {0};
|
471
|
-
|
472
|
-
if (type_symbols[0] == 0) {
|
473
|
-
int i;
|
474
|
-
for (i=0; i<T_MASK; i++) {
|
475
|
-
type_symbols[i] = ID2SYM(rb_intern(type_name(i)));
|
476
|
-
}
|
477
|
-
}
|
478
532
|
|
479
533
|
i = 0;
|
480
534
|
if (arg->keys & KEY_PATH) {
|
@@ -493,7 +547,7 @@ aggregate_result_i(st_data_t key, st_data_t val, void *data)
|
|
493
547
|
if (arg->keys & KEY_TYPE) {
|
494
548
|
int sym_index = key_buff->data[i++];
|
495
549
|
assert(T_MASK > sym_index);
|
496
|
-
rb_ary_push(k,
|
550
|
+
rb_ary_push(k, type_sym(sym_index));
|
497
551
|
}
|
498
552
|
if (arg->keys & KEY_CLASS) {
|
499
553
|
VALUE klass = key_buff->data[i++];
|
@@ -532,6 +586,32 @@ aggregate_live_object_i(st_data_t key, st_data_t val, void *data)
|
|
532
586
|
return ST_CONTINUE;
|
533
587
|
}
|
534
588
|
|
589
|
+
static int
|
590
|
+
lifetime_table_for_live_objects_i(st_data_t key, st_data_t val, st_data_t data)
|
591
|
+
{
|
592
|
+
struct allocation_info *info = (struct allocation_info *)val;
|
593
|
+
VALUE h = (VALUE)data;
|
594
|
+
int type = info->flags & T_MASK;
|
595
|
+
VALUE sym = type_sym(type);
|
596
|
+
size_t age = rb_gc_count() - info->generation;
|
597
|
+
VALUE line;
|
598
|
+
size_t count, i;
|
599
|
+
|
600
|
+
if ((line = rb_hash_aref(h, sym)) == Qnil) {
|
601
|
+
line = rb_ary_new();
|
602
|
+
rb_hash_aset(h, sym, line);
|
603
|
+
}
|
604
|
+
|
605
|
+
for (i=RARRAY_LEN(line); i<age+1; i++) {
|
606
|
+
rb_ary_push(line, INT2FIX(0));
|
607
|
+
}
|
608
|
+
|
609
|
+
count = NUM2SIZET(RARRAY_AREF(line, age));
|
610
|
+
RARRAY_ASET(line, age, SIZET2NUM(count + 1));
|
611
|
+
|
612
|
+
return ST_CONTINUE;
|
613
|
+
}
|
614
|
+
|
535
615
|
static VALUE
|
536
616
|
aggregate_result(struct traceobj_arg *arg)
|
537
617
|
{
|
@@ -560,15 +640,33 @@ aggregate_result(struct traceobj_arg *arg)
|
|
560
640
|
|
561
641
|
arg->aggregate_table = dead_object_aggregate_table;
|
562
642
|
}
|
563
|
-
return aar.result;
|
564
|
-
}
|
565
643
|
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
644
|
+
/* lifetime table */
|
645
|
+
if (arg->lifetime_table) {
|
646
|
+
VALUE h = rb_hash_new();
|
647
|
+
int i;
|
648
|
+
|
649
|
+
for (i=0; i<T_MASK; i++) {
|
650
|
+
size_t *line = arg->lifetime_table[i];
|
651
|
+
|
652
|
+
if (line) {
|
653
|
+
size_t len = line[0], j;
|
654
|
+
VALUE ary = rb_ary_new();
|
655
|
+
VALUE sym = type_sym(i);
|
656
|
+
|
657
|
+
for (j=0; j<len; j++) {
|
658
|
+
rb_ary_push(ary, SIZET2NUM(line[j+1]));
|
659
|
+
}
|
660
|
+
|
661
|
+
rb_hash_aset(h, sym, ary);
|
662
|
+
}
|
663
|
+
}
|
664
|
+
|
665
|
+
st_foreach(arg->object_table, lifetime_table_for_live_objects_i, (st_data_t)h);
|
666
|
+
rb_ivar_set(rb_mAllocationTracer, rb_intern("lifetime_table"), h);
|
667
|
+
}
|
668
|
+
|
669
|
+
return aar.result;
|
572
670
|
}
|
573
671
|
|
574
672
|
static VALUE
|
@@ -577,8 +675,6 @@ allocation_tracer_result(VALUE self)
|
|
577
675
|
VALUE result;
|
578
676
|
struct traceobj_arg *arg = get_traceobj_arg();
|
579
677
|
|
580
|
-
check_tracer_running();
|
581
|
-
|
582
678
|
disable_newobj_hook();
|
583
679
|
result = aggregate_result(arg);
|
584
680
|
enable_newobj_hook();
|
@@ -620,10 +716,20 @@ allocation_tracer_trace(VALUE self)
|
|
620
716
|
return Qnil;
|
621
717
|
}
|
622
718
|
|
719
|
+
static VALUE
|
720
|
+
allocation_tracer_stop(VALUE self)
|
721
|
+
{
|
722
|
+
VALUE result;
|
723
|
+
|
724
|
+
disable_newobj_hook();
|
725
|
+
result = aggregate_result(get_traceobj_arg());
|
726
|
+
stop_alloc_hooks(self);
|
727
|
+
return result;
|
728
|
+
}
|
729
|
+
|
623
730
|
static VALUE
|
624
731
|
allocation_tracer_pause(VALUE self)
|
625
732
|
{
|
626
|
-
check_tracer_running();
|
627
733
|
disable_newobj_hook();
|
628
734
|
return Qnil;
|
629
735
|
}
|
@@ -631,7 +737,6 @@ allocation_tracer_pause(VALUE self)
|
|
631
737
|
static VALUE
|
632
738
|
allocation_tracer_resume(VALUE self)
|
633
739
|
{
|
634
|
-
check_tracer_running();
|
635
740
|
enable_newobj_hook();
|
636
741
|
return Qnil;
|
637
742
|
}
|
@@ -689,6 +794,39 @@ allocation_tracer_header(VALUE self)
|
|
689
794
|
return ary;
|
690
795
|
}
|
691
796
|
|
797
|
+
static VALUE
|
798
|
+
allocation_tracer_lifetime_table_setup(VALUE self, VALUE set)
|
799
|
+
{
|
800
|
+
struct traceobj_arg * arg = get_traceobj_arg();
|
801
|
+
|
802
|
+
if (arg->running) {
|
803
|
+
rb_raise(rb_eRuntimeError, "can't change configuration during running");
|
804
|
+
}
|
805
|
+
|
806
|
+
if (RTEST(set)) {
|
807
|
+
if (arg->lifetime_table == NULL) {
|
808
|
+
arg->lifetime_table = (size_t **)calloc(sizeof(size_t **), T_MASK);
|
809
|
+
|
810
|
+
}
|
811
|
+
}
|
812
|
+
else {
|
813
|
+
if (arg->lifetime_table != NULL) {
|
814
|
+
free(arg->lifetime_table);
|
815
|
+
arg->lifetime_table = NULL;
|
816
|
+
}
|
817
|
+
}
|
818
|
+
|
819
|
+
return Qnil;
|
820
|
+
}
|
821
|
+
|
822
|
+
static VALUE
|
823
|
+
allocation_tracer_lifetime_table(VALUE self)
|
824
|
+
{
|
825
|
+
VALUE result = rb_ivar_get(rb_mAllocationTracer, rb_intern("lifetime_table"));
|
826
|
+
rb_ivar_set(rb_mAllocationTracer, rb_intern("lifetime_table"), Qnil);
|
827
|
+
return result;
|
828
|
+
}
|
829
|
+
|
692
830
|
void
|
693
831
|
Init_allocation_tracer(void)
|
694
832
|
{
|
@@ -706,4 +844,7 @@ Init_allocation_tracer(void)
|
|
706
844
|
rb_define_module_function(mod, "clear", allocation_tracer_clear, 0);
|
707
845
|
rb_define_module_function(mod, "setup", allocation_tracer_setup, -1);
|
708
846
|
rb_define_module_function(mod, "header", allocation_tracer_header, 0);
|
847
|
+
|
848
|
+
rb_define_module_function(mod, "lifetime_table_setup", allocation_tracer_lifetime_table_setup, 1);
|
849
|
+
rb_define_module_function(mod, "lifetime_table", allocation_tracer_lifetime_table, 0);
|
709
850
|
}
|
@@ -164,4 +164,43 @@ describe ObjectSpace::AllocationTracer do
|
|
164
164
|
end
|
165
165
|
end
|
166
166
|
end
|
167
|
+
|
168
|
+
describe 'collect lifetime_table' do
|
169
|
+
before do
|
170
|
+
ObjectSpace::AllocationTracer.lifetime_table_setup true
|
171
|
+
end
|
172
|
+
|
173
|
+
after do
|
174
|
+
ObjectSpace::AllocationTracer.lifetime_table_setup false
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should make lifetime table' do
|
178
|
+
ObjectSpace::AllocationTracer.trace do
|
179
|
+
100000.times{
|
180
|
+
Object.new
|
181
|
+
''
|
182
|
+
}
|
183
|
+
end
|
184
|
+
table = ObjectSpace::AllocationTracer.lifetime_table
|
185
|
+
|
186
|
+
expect(table[:T_OBJECT].inject(&:+)).to be >= 10_000
|
187
|
+
expect(table[:T_STRING].inject(&:+)).to be >= 10_000
|
188
|
+
expect(table[:T_NONE]).to be nil
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'should nil when ObjectSpace::AllocationTracer.lifetime_table_setup is nil' do
|
192
|
+
ObjectSpace::AllocationTracer.lifetime_table_setup false
|
193
|
+
|
194
|
+
ObjectSpace::AllocationTracer.trace do
|
195
|
+
100000.times{
|
196
|
+
Object.new
|
197
|
+
''
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
table = ObjectSpace::AllocationTracer.lifetime_table
|
202
|
+
|
203
|
+
expect(table).to be nil
|
204
|
+
end
|
205
|
+
end
|
167
206
|
end
|
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.
|
4
|
+
version: 0.3.0
|
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-
|
11
|
+
date: 2014-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -84,7 +84,6 @@ files:
|
|
84
84
|
- ext/allocation_tracer/allocation_tracer.c
|
85
85
|
- ext/allocation_tracer/extconf.rb
|
86
86
|
- lib/allocation_tracer.rb
|
87
|
-
- lib/allocation_tracer/allocation_tracer.so
|
88
87
|
- lib/allocation_tracer/trace.rb
|
89
88
|
- lib/allocation_tracer/version.rb
|
90
89
|
- spec/allocation_tracer_spec.rb
|
Binary file
|