gc_tracer 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +24 -0
- data/ext/gc_tracer/gc_tracer.c +92 -10
- data/lib/gc_tracer/version.rb +1 -1
- data/public/viewer.html +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02c2e3a73f9c81c909ea34661ee28e724e46ae6a
|
4
|
+
data.tar.gz: f9ecb1757af0bf11518f6a4bf0065568fc1f6d78
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c442b07afc88814c7dd2687872ba1a260bd6cfd26951596b488291fb31e06787265c1c9c2d1db353be6c712cfa209bfb91dc900a73e747d946d8ea4d7ab30b1d
|
7
|
+
data.tar.gz: ccb123ceff8944ef0405c37793d192eabbc8d515c364da02aaf5ca1b3ec4872c82487467a946a96264f18d3237fb1168b2f03318f89b6e1fc35aeb9905517676
|
data/README.md
CHANGED
@@ -20,6 +20,8 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
+
### Logging
|
24
|
+
|
23
25
|
You can get GC statistics information in block form like this:
|
24
26
|
|
25
27
|
```ruby
|
@@ -52,6 +54,28 @@ at each events, there are one of:
|
|
52
54
|
|
53
55
|
For one GC, you can get all three lines.
|
54
56
|
|
57
|
+
### ObjectSpace recorder
|
58
|
+
|
59
|
+
You can records objspace snapshots on each events. Snapshots are stored
|
60
|
+
in the [PPM (P6) format] (http://en.wikipedia.org/wiki/Netpbm_format).
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
require 'gc_tracer'
|
64
|
+
GC::Tracer.start_objspace_recording(dirname) do
|
65
|
+
# do something
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
All PPM images are stored in dirname/ppm/.
|
70
|
+
|
71
|
+
If you have netpbm package and pnmtopng command,
|
72
|
+
bin/objspace_recorder_convert.rb converts all ppm images into png files.
|
73
|
+
Converted png images stored into dirname/png/.
|
74
|
+
|
75
|
+
You can view all converted png images with public/viewer.html.
|
76
|
+
|
77
|
+
This feature is supported only latest Ruby versions (2.2, and later).
|
78
|
+
|
55
79
|
## Contributing
|
56
80
|
|
57
81
|
1. Fork it ( http://github.com/ko1/gc_tracer/fork )
|
data/ext/gc_tracer/gc_tracer.c
CHANGED
@@ -505,22 +505,85 @@ categorical_color10(int n)
|
|
505
505
|
}
|
506
506
|
|
507
507
|
static int
|
508
|
-
|
508
|
+
categorical_color20(int n)
|
509
|
+
{
|
510
|
+
const int colors[] = {
|
511
|
+
0x1f77b4,
|
512
|
+
0xaec7e8,
|
513
|
+
0xff7f0e,
|
514
|
+
0xffbb78,
|
515
|
+
0x2ca02c,
|
516
|
+
0x98df8a,
|
517
|
+
0xd62728,
|
518
|
+
0xff9896,
|
519
|
+
0x9467bd,
|
520
|
+
0xc5b0d5,
|
521
|
+
0x8c564b,
|
522
|
+
0xc49c94,
|
523
|
+
0xe377c2,
|
524
|
+
0xf7b6d2,
|
525
|
+
0x7f7f7f,
|
526
|
+
0xc7c7c7,
|
527
|
+
0xbcbd22,
|
528
|
+
0xdbdb8d,
|
529
|
+
0x17becf,
|
530
|
+
0x9edae5,
|
531
|
+
};
|
532
|
+
assert(n < 20);
|
533
|
+
return colors[n];
|
534
|
+
}
|
535
|
+
|
536
|
+
static int
|
537
|
+
object_age_picker(VALUE v) {
|
509
538
|
if (RB_TYPE_P(v, T_NONE)) {
|
510
|
-
return 0;
|
539
|
+
return categorical_color10(0);
|
511
540
|
}
|
512
541
|
else {
|
513
542
|
if (OBJ_PROMOTED(v)) {
|
514
543
|
/* old */
|
515
|
-
return 1;
|
544
|
+
return categorical_color10(1);
|
516
545
|
}
|
517
546
|
else {
|
518
547
|
/* young */
|
519
|
-
return 2;
|
548
|
+
return categorical_color10(2);
|
520
549
|
}
|
521
550
|
}
|
522
551
|
}
|
523
552
|
|
553
|
+
static int
|
554
|
+
object_type_picker(VALUE v) {
|
555
|
+
int type = BUILTIN_TYPE(v);
|
556
|
+
int color = 0;
|
557
|
+
switch (type) {
|
558
|
+
case RUBY_T_NONE:
|
559
|
+
case RUBY_T_OBJECT:
|
560
|
+
case RUBY_T_CLASS:
|
561
|
+
case RUBY_T_MODULE:
|
562
|
+
case RUBY_T_FLOAT:
|
563
|
+
case RUBY_T_STRING:
|
564
|
+
case RUBY_T_REGEXP:
|
565
|
+
case RUBY_T_ARRAY:
|
566
|
+
case RUBY_T_HASH:
|
567
|
+
case RUBY_T_STRUCT:
|
568
|
+
case RUBY_T_BIGNUM:
|
569
|
+
case RUBY_T_FILE:
|
570
|
+
case RUBY_T_DATA:
|
571
|
+
case RUBY_T_MATCH:
|
572
|
+
case RUBY_T_COMPLEX:
|
573
|
+
case RUBY_T_RATIONAL: /* 0x0f */
|
574
|
+
color = type;
|
575
|
+
break;
|
576
|
+
case RUBY_T_NODE:
|
577
|
+
case RUBY_T_ICLASS:
|
578
|
+
case RUBY_T_ZOMBIE:
|
579
|
+
color = type - 11;
|
580
|
+
break;
|
581
|
+
default:
|
582
|
+
rb_bug("object_type_picker: unreachable (type: %d)", type);
|
583
|
+
}
|
584
|
+
return categorical_color20(color);
|
585
|
+
}
|
586
|
+
|
524
587
|
static int
|
525
588
|
objspace_recording_i(void *start, void *end, size_t stride, void *data)
|
526
589
|
{
|
@@ -531,8 +594,7 @@ objspace_recording_i(void *start, void *end, size_t stride, void *data)
|
|
531
594
|
|
532
595
|
for (i=0; i<size; i++) {
|
533
596
|
VALUE v = (VALUE)start + i * stride;
|
534
|
-
|
535
|
-
set_color(&buff[i*3], categorical_color10(color_index));
|
597
|
+
set_color(&buff[i*3], (*objspace_recorder_color_picker)(v));
|
536
598
|
}
|
537
599
|
for (; i<HEAP_OBJ_LIMIT; i++) {
|
538
600
|
set_color(&buff[i*3], 0);
|
@@ -589,11 +651,23 @@ gc_tracer_stop_objspace_recording(VALUE self)
|
|
589
651
|
}
|
590
652
|
|
591
653
|
static VALUE
|
592
|
-
gc_tracer_start_objspace_recording(VALUE
|
654
|
+
gc_tracer_start_objspace_recording(int argc, VALUE *argv, VALUE self)
|
593
655
|
{
|
594
656
|
if (objspace_recorder.enabled == Qfalse) {
|
595
657
|
int i;
|
596
658
|
VALUE ppmdir;
|
659
|
+
VALUE dirname;
|
660
|
+
VALUE picker_type = ID2SYM(rb_intern("age"));
|
661
|
+
|
662
|
+
switch (argc) {
|
663
|
+
case 2:
|
664
|
+
picker_type = argv[1];
|
665
|
+
case 1:
|
666
|
+
dirname = argv[0];
|
667
|
+
break;
|
668
|
+
default:
|
669
|
+
rb_raise(rb_eArgError, "expect 1 or 2 arguments, but %d", argc);
|
670
|
+
}
|
597
671
|
|
598
672
|
/* setup */
|
599
673
|
if (rb_funcall(rb_cFile, rb_intern("directory?"), 1, dirname) != Qtrue) {
|
@@ -603,7 +677,15 @@ gc_tracer_start_objspace_recording(VALUE self, VALUE dirname)
|
|
603
677
|
rb_funcall(rb_cDir, rb_intern("mkdir"), 1, ppmdir);
|
604
678
|
}
|
605
679
|
|
606
|
-
|
680
|
+
if (picker_type == ID2SYM(rb_intern("age"))) {
|
681
|
+
objspace_recorder_color_picker = object_age_picker;
|
682
|
+
}
|
683
|
+
else if (picker_type == ID2SYM(rb_intern("type"))) {
|
684
|
+
objspace_recorder_color_picker = object_type_picker;
|
685
|
+
}
|
686
|
+
else {
|
687
|
+
rb_raise(rb_eArgError, "unsupported picker type: %s", rb_id2name(SYM2ID(picker_type)));
|
688
|
+
}
|
607
689
|
|
608
690
|
HEAP_OBJ_LIMIT = FIX2INT(rb_hash_aref(
|
609
691
|
rb_const_get(rb_mGC, rb_intern("INTERNAL_CONSTANTS")),
|
@@ -662,8 +744,8 @@ Init_gc_tracer(void)
|
|
662
744
|
|
663
745
|
/* recording methods */
|
664
746
|
#ifdef HAVE_RB_OBJSPACE_EACH_OBJECTS_WITHOUT_SETUP
|
665
|
-
rb_define_module_function(mod, "start_objspace_recording", gc_tracer_start_objspace_recording, 1);
|
666
|
-
rb_define_module_function(mod, "stop_objspace_recording", gc_tracer_stop_objspace_recording,
|
747
|
+
rb_define_module_function(mod, "start_objspace_recording", gc_tracer_start_objspace_recording, -1);
|
748
|
+
rb_define_module_function(mod, "stop_objspace_recording", gc_tracer_stop_objspace_recording, 0);
|
667
749
|
#endif
|
668
750
|
|
669
751
|
/* setup default banners */
|
data/lib/gc_tracer/version.rb
CHANGED
data/public/viewer.html
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gc_tracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
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-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|