# module 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'

    GC::Profiler.report

    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(VALUE _)
    {
        rb_objspace_t *objspace = &rb_objspace;
        void *p = objspace->profile.records;
        objspace->profile.records = NULL;
        objspace->profile.size = 0;
        objspace->profile.next_index = 0;
        objspace->profile.current_record = 0;
        if (p) {
            free(p);
        }
        return Qnil;
    }

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

Stops the `GC` profiler.

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

        objspace->profile.run = FALSE;
        objspace->profile.current_record = 0;
        return Qnil;
    }

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

Starts the `GC` profiler.

    static VALUE
    gc_profile_enable(VALUE _)
    {
        rb_objspace_t *objspace = &rb_objspace;
        objspace->profile.run = TRUE;
        objspace->profile.current_record = 0;
        return Qnil;
    }

GC::Profiler.enabled? → 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 RBOOL(objspace->profile.run);
    }

GC::Profiler.raw_data → [Hash, ...] click to toggle source

Returns an `Array` of individual raw profile data Hashes ordered from earliest to latest by `:GC_INVOKE_TIME`.

For example:

    [
      {
         :GC_TIME=>1.3000000000000858e-05,
         :GC_INVOKE_TIME=>0.010634999999999999,
         :HEAP_USE_SIZE=>289640,
         :HEAP_TOTAL_SIZE=>588960,
         :HEAP_TOTAL_OBJECTS=>14724,
         :GC_IS_MARKED=>false
      },
      # ...
    ]

The keys mean:

`:GC_TIME`

  `Time` elapsed in seconds for this `GC` run

`:GC_INVOKE_TIME`

  `Time` elapsed in seconds from startup to when the `GC` was invoked

`:HEAP_USE_SIZE`

  Total bytes of heap used

`:HEAP_TOTAL_SIZE`

  Total size of heap in bytes

`:HEAP_TOTAL_OBJECTS`

  Total number of objects

`:GC_IS_MARKED`

  Returns `true` if the `GC` is in mark phase

If ruby was built with `GC_PROFILE_MORE_DETAIL`, you will also have access to the following hash keys:

`:GC_MARK_TIME`
`:GC_SWEEP_TIME`
`:ALLOCATE_INCREASE`
`:ALLOCATE_LIMIT`
`:HEAP_USE_PAGES`
`:HEAP_LIVE_OBJECTS`
`:HEAP_FREE_OBJECTS`
`:HAVE_FINALIZE`

    static VALUE
    gc_profile_record_get(VALUE _)
    {
        VALUE prof;
        VALUE gc_profile = rb_ary_new();
        size_t i;
        rb_objspace_t *objspace = (&rb_objspace);

        if (!objspace->profile.run) {
            return Qnil;
        }

        for (i =0; i < objspace->profile.next_index; i++) {
            gc_profile_record *record = &objspace->profile.records[i];

            prof = rb_hash_new();
            rb_hash_aset(prof, ID2SYM(rb_intern("GC_FLAGS")), gc_info_decode(0, rb_hash_new(), record->flags));
            rb_hash_aset(prof, ID2SYM(rb_intern("GC_TIME")), DBL2NUM(record->gc_time));
            rb_hash_aset(prof, ID2SYM(rb_intern("GC_INVOKE_TIME")), DBL2NUM(record->gc_invoke_time));
            rb_hash_aset(prof, ID2SYM(rb_intern("HEAP_USE_SIZE")), SIZET2NUM(record->heap_use_size));
            rb_hash_aset(prof, ID2SYM(rb_intern("HEAP_TOTAL_SIZE")), SIZET2NUM(record->heap_total_size));
            rb_hash_aset(prof, ID2SYM(rb_intern("HEAP_TOTAL_OBJECTS")), SIZET2NUM(record->heap_total_objects));
            rb_hash_aset(prof, ID2SYM(rb_intern("MOVED_OBJECTS")), SIZET2NUM(record->moved_objects));
            rb_hash_aset(prof, ID2SYM(rb_intern("GC_IS_MARKED")), Qtrue);
    #if GC_PROFILE_MORE_DETAIL
            rb_hash_aset(prof, ID2SYM(rb_intern("GC_MARK_TIME")), DBL2NUM(record->gc_mark_time));
            rb_hash_aset(prof, ID2SYM(rb_intern("GC_SWEEP_TIME")), DBL2NUM(record->gc_sweep_time));
            rb_hash_aset(prof, ID2SYM(rb_intern("ALLOCATE_INCREASE")), SIZET2NUM(record->allocate_increase));
            rb_hash_aset(prof, ID2SYM(rb_intern("ALLOCATE_LIMIT")), SIZET2NUM(record->allocate_limit));
            rb_hash_aset(prof, ID2SYM(rb_intern("HEAP_USE_PAGES")), SIZET2NUM(record->heap_use_pages));
            rb_hash_aset(prof, ID2SYM(rb_intern("HEAP_LIVE_OBJECTS")), SIZET2NUM(record->heap_live_objects));
            rb_hash_aset(prof, ID2SYM(rb_intern("HEAP_FREE_OBJECTS")), SIZET2NUM(record->heap_free_objects));

            rb_hash_aset(prof, ID2SYM(rb_intern("REMOVING_OBJECTS")), SIZET2NUM(record->removing_objects));
            rb_hash_aset(prof, ID2SYM(rb_intern("EMPTY_OBJECTS")), SIZET2NUM(record->empty_objects));

            rb_hash_aset(prof, ID2SYM(rb_intern("HAVE_FINALIZE")), RBOOL(record->flags & GPR_FLAG_HAVE_FINALIZE));
    #endif

    #if RGENGC_PROFILE > 0
            rb_hash_aset(prof, ID2SYM(rb_intern("OLD_OBJECTS")), SIZET2NUM(record->old_objects));
            rb_hash_aset(prof, ID2SYM(rb_intern("REMEMBERED_NORMAL_OBJECTS")), SIZET2NUM(record->remembered_normal_objects));
            rb_hash_aset(prof, ID2SYM(rb_intern("REMEMBERED_SHADY_OBJECTS")), SIZET2NUM(record->remembered_shady_objects));
    #endif
            rb_ary_push(gc_profile, prof);
        }

        return gc_profile;
    }

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;

        out = (!rb_check_arity(argc, 0, 1) ? rb_stdout : argv[0]);
        gc_profile_dump_on(out, rb_io_write);

        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(VALUE _)
    {
        VALUE str = rb_str_buf_new(0);
        gc_profile_dump_on(str, rb_str_buf_append);
        return str;
    }

GC::Profiler.total_time → float click to toggle source

The total time used for garbage collection in seconds

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

        if (objspace->profile.run && objspace->profile.next_index > 0) {
            size_t i;
            size_t count = objspace->profile.next_index;

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