Project

General

Profile

Actions

Feature #1628

closed

GC.stat

Added by ko1 (Koichi Sasada) almost 15 years ago. Updated almost 13 years ago.

Status:
Closed
Target version:
[ruby-dev:38607]

Description

=begin
 ささだです.

 現在の GC 関連の状態を表示するためのメソッド GC.stat を追加するのはど
うでしょうか.

{:count=>1, # これまで GC が起こった回数
:elapsed_time=>0.004, # これまで GC にかかったユーザ時間
:heap_used=>20, # 利用中の heap の数
:heap_length=>22, # 確保した heap の数
:heap_live_slot=>4742, # 生きている slot の数 (*1)
:heap_free_slot=>5056, # 空いている slot の数 (*1)
:heap_waiting_finalize_slot=>23} # ファイナライザを待っている slot の数

*1: 一番最後の GC でカウント.

Gauche では gc-stat というものがある,と shiro さんに聞いたもので.

gosh> (gc-stat)
((:total-heap-size 786432) (:free-bytes 163840) (:bytes-since-gc 532376)
(:total-bytes 532352))

Index: gc.c

--- gc.c (リビジョン 23689)
+++ gc.c (作業コピー)
@@ -323,6 +323,9 @@ typedef struct rb_objspace {
size_t length;
size_t used;
size_t longlife_used;

  • size_t total_live_slot;
  • size_t total_free_slot;
  • size_t total_waiting_finalize_slot;
    RVALUE *freelist;
    RVALUE *longlife_freelist;
    RVALUE *range[2];
    @@ -355,7 +358,8 @@ typedef struct rb_objspace {
    double invoke_time;
    } profile;
    struct gc_list *global_list;
  • unsigned int count;
  • size_t count;
  • double elapsed_time;
    int gc_stress;
    } rb_objspace_t;

@@ -933,7 +937,8 @@ assign_heap_slot(rb_objspace_t *objspace
if (lomem == 0 || lomem > p) lomem = p;
if (himem < pend) himem = pend;
if (lifetime == lifetime_longlife) objspace->heap.longlife_used++;

  • heaps_used++;
  • objspace->heap.used++;

  • objspace->heap.total_free_slot += objs;

    while (p < pend) {
    p->as.free.flags = 0;
    @@ -1832,7 +1837,7 @@ static void
    gc_sweep(rb_objspace_t *objspace)
    {
    RVALUE *p, *pend, *final_list;

  • size_t freed = 0;
  • size_t freed = 0, waiting_finalize = 0;
    size_t i;
    size_t live = 0, free_min = 0, do_heap_free = 0;

@@ -1868,6 +1873,7 @@ gc_sweep(rb_objspace_t *objspace)
p->as.free.next = final_list;
final_list = p;
final_num++;

  •      waiting_finalize++;
     }
     else {
         add_freelist(objspace, &freelist, p);
    

@@ -1877,6 +1883,7 @@ gc_sweep(rb_objspace_t objspace)
else if (BUILTIN_TYPE(p) == T_ZOMBIE) {
/
objects to be finalized /
/
do nothing remain marked */

  •  waiting_finalize++;
     }
     else {
     RBASIC(p)->flags &= ~FL_MARK;
    

@@ -1923,6 +1930,10 @@ gc_sweep(rb_objspace_t *objspace)
free_unused_heaps(objspace);
GC_PROF_SET_HEAP_INFO;
}
+

  • objspace->heap.total_live_slot = live;
  • objspace->heap.total_free_slot = freed;
  • objspace->heap.total_waiting_finalize_slot = waiting_finalize;
    }

static void
@@ -2207,6 +2218,8 @@ garbage_collect(rb_objspace_t *objspace)
{
struct gc_list *list;
rb_thread_t *th = GET_THREAD();

  • double invoke_time = getrusage_time();

  • INIT_GC_PROF_PARAMS;

    if (GC_NOTIFY) printf("start garbage_collect()\n");
    @@ -2286,6 +2299,8 @@ garbage_collect(rb_objspace_t *objspace)

    GC_PROF_TIMER_STOP;
    if (GC_NOTIFY) printf("end garbage_collect()\n");

  • objspace->elapsed_time += getrusage_time() - invoke_time;

  • return Qtrue;
    }

@@ -2950,6 +2965,33 @@ gc_count(VALUE self)
return UINT2NUM((&rb_objspace)->count);
}

+/*

    • call-seq:
    • GC.stat -> Hash
      
    • Return information about GC.
    • It returns several information about GC:
    • total count, elapesed time, heap size, and so on.
  • */
    +static VALUE
    +gc_stat(VALUE self)
    +{
  • VALUE hash = rb_hash_new();
  • rb_objspace_t *objspace = &rb_objspace;
  • rb_hash_aset(hash, ID2SYM(rb_intern("count")),
    SIZET2NUM(objspace->count));
  • rb_hash_aset(hash, ID2SYM(rb_intern("elapsed_time")),
    DBL2NUM(objspace->elapsed_time));
  • rb_hash_aset(hash, ID2SYM(rb_intern("heap_used")),
    SIZET2NUM(objspace->heap.used));
  • rb_hash_aset(hash, ID2SYM(rb_intern("heap_length")),
    SIZET2NUM(objspace->heap.length));
  • rb_hash_aset(hash, ID2SYM(rb_intern("heap_live_slot")),
    SIZET2NUM(objspace->heap.total_live_slot));
  • rb_hash_aset(hash, ID2SYM(rb_intern("heap_free_slot")),
    SIZET2NUM(objspace->heap.total_free_slot));
  • rb_hash_aset(hash, ID2SYM(rb_intern("heap_waiting_finalize_slot")),
    SIZET2NUM(objspace->heap.total_waiting_finalize_slot));
  • return hash;
    +}

#if CALC_EXACT_MALLOC_SIZE
/*

  • call-seq:
    @@ -3122,6 +3164,7 @@ Init_GC(void)
    rb_define_singleton_method(rb_mGC, "stress", gc_stress_get, 0);
    rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1);
    rb_define_singleton_method(rb_mGC, "count", gc_count, 0);
  • rb_define_singleton_method(rb_mGC, "stat", gc_stat, 0);
    rb_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0);

    rb_mProfiler = rb_define_module_under(rb_mGC, "Profiler");

--
// SASADA Koichi at atdot dot net
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0