In Files

  • gc.c

GC::Profiler

The GC profiler provides access to information on GC runs including time, length and object space size.

Example:

GC::Profiler.enable

require 'rdoc/rdoc'

puts GC::Profiler.result

GC::Profiler.disable

See also GC.count, GC.malloc_allocated_size and GC.malloc_allocations

Public Class Methods

GC::Profiler.clear → nil click to toggle source

Clears the GC profiler data.

 
               static VALUE
gc_profile_clear(void)
{
    rb_objspace_t *objspace = &rb_objspace;
    MEMZERO(objspace->profile.record, gc_profile_record, objspace->profile.size);
    objspace->profile.count = 0;
    return Qnil;
}
            
GC::Profiler.disable → nil click to toggle source

Stops the GC profiler.

 
               static VALUE
gc_profile_disable(void)
{
    rb_objspace_t *objspace = &rb_objspace;

    objspace->profile.run = FALSE;
    return Qnil;
}
            
GC::Profiler.enable → nil click to toggle source

Starts the GC profiler.

 
               static VALUE
gc_profile_enable(void)
{
    rb_objspace_t *objspace = &rb_objspace;

    objspace->profile.run = TRUE;
    return Qnil;
}
            
GC::Profiler.enable? → true or false click to toggle source

The current status of GC profile mode.

 
               static VALUE
gc_profile_enable_get(VALUE self)
{
    rb_objspace_t *objspace = &rb_objspace;
    return objspace->profile.run ? Qtrue : Qfalse;
}
            
GC::Profiler.report click to toggle source
GC::Profiler.report io

Writes the GC::Profiler#result to $stdout or the given IO object.

 
               static VALUE
gc_profile_report(int argc, VALUE *argv, VALUE self)
{
    VALUE out;

    if (argc == 0) {
        out = rb_stdout;
    }
    else {
        rb_scan_args(argc, argv, "01", &out);
    }
    rb_io_write(out, gc_profile_result());

    return Qnil;
}
            
GC::Profiler.result → String click to toggle source

Returns a profile data report such as:

GC 1 invokes.
Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)         Total Object                    GC time(ms)
    1               0.012               159240               212940                10647         0.00000000000001530000
 
               static VALUE
gc_profile_result(void)
{
    rb_objspace_t *objspace = &rb_objspace;
    VALUE record;
    VALUE result;
    int i, index;

    record = gc_profile_record_get();
    if (objspace->profile.run && objspace->profile.count) {
        result = rb_sprintf("GC %d invokes.\n", NUM2INT(gc_count(0)));
        index = 1;
        rb_str_cat2(result, "Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)         Total Object                    GC Time(ms)\n");
        for (i = 0; i < (int)RARRAY_LEN(record); i++) {
            VALUE r = RARRAY_PTR(record)[i];
#if !GC_PROFILE_MORE_DETAIL
            if (rb_hash_aref(r, ID2SYM(rb_intern("GC_IS_MARKED")))) {
#endif
            rb_str_catf(result, "%5d %19.3f %20"PRIuSIZE" %20"PRIuSIZE" %20"PRIuSIZE" %30.20f\n",
                        index++, NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_INVOKE_TIME")))),
                        (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_USE_SIZE")))),
                        (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_TOTAL_SIZE")))),
                        (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_TOTAL_OBJECTS")))),
                        NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_TIME"))))*1000);
#if !GC_PROFILE_MORE_DETAIL
            }
#endif
        }
#if GC_PROFILE_MORE_DETAIL
        rb_str_cat2(result, "\n\n");
        rb_str_cat2(result, "More detail.\n");
        rb_str_cat2(result, "Index Allocate Increase    Allocate Limit  Use Slot  Have Finalize             Mark Time(ms)            Sweep Time(ms)\n");
        index = 1;
        for (i = 0; i < (int)RARRAY_LEN(record); i++) {
            VALUE r = RARRAY_PTR(record)[i];
            rb_str_catf(result, "%5d %17"PRIuSIZE" %17"PRIuSIZE" %9"PRIuSIZE" %14s %25.20f %25.20f\n",
                        index++, (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("ALLOCATE_INCREASE")))),
                        (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("ALLOCATE_LIMIT")))),
                        (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_USE_SLOTS")))),
                        rb_hash_aref(r, ID2SYM(rb_intern("HAVE_FINALIZE")))? "true" : "false",
                        NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_MARK_TIME"))))*1000,
                        NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_SWEEP_TIME"))))*1000);
        }
#endif
    }
    else {
        result = rb_str_new2("");
    }
    return result;
}
            
GC::Profiler.total_time → float click to toggle source

The total time used for garbage collection in milliseconds

 
               static VALUE
gc_profile_total_time(VALUE self)
{
    double time = 0;
    rb_objspace_t *objspace = &rb_objspace;
    size_t i;

    if (objspace->profile.run && objspace->profile.count) {
        for (i = 0; i < objspace->profile.count; i++) {
            time += objspace->profile.record[i].gc_time;
        }
    }
    return DBL2NUM(time);
}