On this page
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
static VALUE
gc_profile_clear(void)
{
    rb_objspace_t *objspace = &rb_objspace;
    if (GC_PROFILE_RECORD_DEFAULT_SIZE * 2 < objspace->profile.size) {
        objspace->profile.size = GC_PROFILE_RECORD_DEFAULT_SIZE * 2;
        objspace->profile.records = realloc(objspace->profile.records, sizeof(gc_profile_record) * objspace->profile.size);
        if (!objspace->profile.records) {
            rb_memerror();
        }
    }
    MEMZERO(objspace->profile.records, gc_profile_record, objspace->profile.size);
    objspace->profile.next_index = 0;
    objspace->profile.current_record = 0;
    return Qnil;
}Clears the GC profiler data.
static VALUE
gc_profile_disable(void)
{
    rb_objspace_t *objspace = &rb_objspace;
    objspace->profile.run = FALSE;
    objspace->profile.current_record = 0;
    return Qnil;
}Stops the GC profiler.
static VALUE
gc_profile_enable(void)
{
    rb_objspace_t *objspace = &rb_objspace;
    objspace->profile.run = TRUE;
    objspace->profile.current_record = 0;
    return Qnil;
}Starts the GC profiler.
static VALUE
gc_profile_enable_get(VALUE self)
{
    rb_objspace_t *objspace = &rb_objspace;
    return objspace->profile.run ? Qtrue : Qfalse;
}The current status of GC profile mode.
static VALUE
gc_profile_record_get(void)
{
    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("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")), (record->flags & GPR_FLAG_HAVE_FINALIZE) ? Qtrue : Qfalse);
#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;
}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
- :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 trueif 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_result(void)
{
        VALUE str = rb_str_buf_new(0);
        gc_profile_dump_on(str, rb_str_buf_append);
        return str;
}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.00000000000001530000static 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);
}The total time used for garbage collection in seconds
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.