Module: GC::Profiler
| Relationships & Source Files | |
| Defined in: | gc.c |
Overview
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 count, malloc_allocated_size and malloc_allocations
Class Attribute Summary
-
.enabled? ⇒ Boolean
readonly
The current status of
::GCprofile mode.
Class Method Summary
-
.clear ⇒ nil
Clears the
::GCprofiler data. -
.disable ⇒ nil
Stops the
::GCprofiler. -
.enable ⇒ nil
Starts the
::GCprofiler. -
.raw_data ⇒ Array, ...
Returns an
::Arrayof individual raw profile data Hashes ordered from earliest to latest by:GC_INVOKE_TIME. - .report
-
.result ⇒ String
Returns a profile data report such as:
-
.total_time ⇒ Float
The total time used for garbage collection in seconds.
Class Attribute Details
.enabled? ⇒ Boolean (readonly)
The current status of ::GC profile mode.
# File 'gc.c', line 13025
static VALUE
gc_profile_enable_get(VALUE self)
{
rb_objspace_t *objspace = &rb_objspace;
return RBOOL(objspace->profile.run);
}
Class Method Details
.clear ⇒ nil
Clears the ::GC profiler data.
# File 'gc.c', line 12712
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;
}
.disable ⇒ nil
Stops the ::GC profiler.
# File 'gc.c', line 13057
static VALUE
gc_profile_disable(VALUE _)
{
rb_objspace_t *objspace = &rb_objspace;
objspace->profile.run = FALSE;
objspace->profile.current_record = 0;
return Qnil;
}
.enable ⇒ nil
Starts the ::GC profiler.
# File 'gc.c', line 13040
static VALUE
gc_profile_enable(VALUE _)
{
rb_objspace_t *objspace = &rb_objspace;
objspace->profile.run = TRUE;
objspace->profile.current_record = 0;
return Qnil;
}
.raw_data ⇒ Array, ...
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
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
# File 'gc.c', line 12777
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;
}
.report
.report(io)
[ GitHub ]
# File 'gc.c', line 12983
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;
}
.result ⇒ String
# File 'gc.c', line 12966
static VALUE
gc_profile_result(VALUE _)
{
VALUE str = rb_str_buf_new(0);
gc_profile_dump_on(str, rb_str_buf_append);
return str;
}
.total_time ⇒ Float
The total time used for garbage collection in seconds
# File 'gc.c', line 13001
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);
}