Bug #8122

[patch] gc: GC.stat improvements and related cleanup

Added by Aman Gupta about 1 year ago. Updated 7 months ago.

[ruby-core:53523]
Status:Closed
Priority:Normal
Assignee:Koichi Sasada
Category:core
Target version:2.1.0
ruby -v:ruby 2.1.0dev (2013-03-19 trunk 39816) [x86_64-darwin12.2.1] Backport:

Description

I propose 4 related patches below. The end result is more information from GC.stat about mark and sweep activity.

1) Rename heap.freenum to heap.sweptnum
This is a purely cosmetic change, to make the purpose of the variable more clear and avoid problems due to misuse later (like we saw in r39811)
I considered some other names: heap.freelistednum, heap.reusednum

2) Add heap.sweepnum
We already calculate heap.marked
num during mark. This is inverse of markednum calculated at the end of mark cycle.
Using this you can monitor progress of sweep cycle: (100% * heap.swept
num / heap.sweepnum)
I considered also: heap.sweeping
num

3) Remove restsweep() from GC.stat
Currently sweep is a side-effect of GC.stat. It makes GC.stat difficult to use for statistics, because it is not constant time operation.
Also, after rest
sweep(), heap.sweptnum == heap.sweepnum, so GC.stat cannot be used to track progress of sweep cycle.

4) Expose new mark/sweep counters via GC.stat

Author: Aman Gupta aman@tmm1.net
Date: Mon Mar 18 18:11:27 2013 -0700

rename heap.free_num to heap.swept_num

diff --git a/gc.c b/gc.c
index 635e3ec..f654e19 100644
--- a/gc.c
+++ b/gc.c
@@ -229,7 +229,7 @@ typedef struct rbobjspace {
RVALUE *range[2];
struct heaps
header freed;
sizet markednum;
- sizet freenum;
+ sizet sweptnum;
sizet freemin;
sizet finalnum;
sizet doheapfree;
@@ -1434,7 +1434,7 @@ finalize
list(rbobjspacet *objspace, RVALUE *p)
objspace->totalfreedobjectnum++;
if (!FL
TEST(p, FL_SINGLETON)) { /
not freeing page */
addslotlocalfreelist(objspace, p);
- objspace->heap.free
num++;
+ objspace->heap.sweptnum++;
}
else {
struct heaps
slot *slot = (struct heapsslot *)(VALUE)RDATA(p)->dmark;
@@ -1921,7 +1921,7 @@ slot
sweep(rbobjspacet *objspace, struct heapsslot *sweepslot)
}
gcclearslotbits(sweepslot);
if (finalnum + freednum + emptynum == sweepslot->header->limit &&
- objspace->heap.freenum > objspace->heap.doheapfree) {
+ objspace->heap.swept
num > objspace->heap.doheapfree) {
RVALUE *pp;

     for (pp = deferred_final_list; pp != final; pp = pp->as.free.next) {

@@ -1938,7 +1938,7 @@ slotsweep(rbobjspacet *objspace, struct heapsslot *sweepslot)
else {
sweep
slot->freenext = NULL;
}
- objspace->heap.free
num += freednum + emptynum;
+ objspace->heap.sweptnum += freednum + emptynum;
}
objspace->total
freedobjectnum += freednum;
objspace->heap.final
num += finalnum;
@@ -1977,7 +1977,7 @@ before
gcsweep(rbobjspacet *objspace)
objspace->heap.do
heapfree = initialfreemin;
}
objspace->heap.sweep
slots = heaps;
- objspace->heap.freenum = 0;
+ objspace->heap.swept
num = 0;
objspace->heap.free_slots = NULL;

 /* sweep unlinked method entries */

@@ -1992,7 +1992,7 @@ aftergcsweep(rbobjspacet *objspace)
size_t inc;

 gc_prof_set_malloc_info(objspace);
  • if (objspace->heap.freenum < objspace->heap.freemin) {
  • if (objspace->heap.sweptnum < objspace->heap.freemin) { setheapsincrement(objspace); heapsincrement(objspace); } @@ -2972,7 +2972,7 @@ rbgcforcerecycle(VALUE p) addslotlocal_freelist(objspace, (RVALUE *)p); } else {
  • objspace->heap.free_num++;
  • objspace->heap.sweptnum++; slot = addslotlocalfreelist(objspace, (RVALUE *)p); if (slot->freenext == NULL) { linkfreeheapslot(objspace, slot); @@ -3205,7 +3205,7 @@ gcstat(int argc, VALUE *argv, VALUE self) rbhashaset(hash, symheaplength, SIZET2NUM(objspace->heap.length)); rbhashaset(hash, symheapincrement, SIZET2NUM(objspace->heap.increment)); rbhashaset(hash, symheaplivenum, SIZET2NUM(objspacelivenum(objspace)));
  • rbhashaset(hash, symheapfreenum, SIZET2NUM(objspace->heap.freenum));
  • rbhashaset(hash, symheapfreenum, SIZET2NUM(objspace->heap.sweptnum)); rbhashaset(hash, symheapfinalnum, SIZET2NUM(objspace->heap.finalnum)); rbhashaset(hash, symtotalallocatedobject, SIZET2NUM(objspace->totalallocatedobjectnum)); rbhashaset(hash, symtotalfreedobject, SIZET2NUM(objspace->totalfreedobjectnum));

Author: Aman Gupta aman@tmm1.net
Date: Mon Mar 18 18:32:58 2013 -0700

add sweep_num

diff --git a/gc.c b/gc.c
index b911d04..c49f1dd 100644
--- a/gc.c
+++ b/gc.c
@@ -229,6 +229,7 @@ typedef struct rbobjspace {
RVALUE *range[2];
struct heaps
header *freed;
sizet markednum;
+ sizet sweepnum;
sizet sweptnum;
sizet freemin;
sizet finalnum;
@@ -2957,6 +2958,7 @@ gcmarks(rbobjspacet *objspace)
gc
profmarktimer_stop(objspace);

 objspace->mark_func_data = prev_mark_func_data;
  • objspace->heap.sweepnum = (heapsused * HEAPOBJLIMIT) - objspace->heap.marked_num;
    }

    /* GC */

Author: Aman Gupta aman@tmm1.net
Date: Mon Mar 18 18:14:10 2013 -0700

remove rest_sweep side-effect from GC.stat

diff --git a/gc.c b/gc.c
index f654e19..b911d04 100644
--- a/gc.c
+++ b/gc.c
@@ -3197,8 +3197,6 @@ gcstat(int argc, VALUE *argv, VALUE self)
hash = rb
hash_new();
}

- rest_sweep(objspace);

 rb_hash_aset(hash, sym_count, SIZET2NUM(objspace->count));
 /* implementation dependent counters */
 rb_hash_aset(hash, sym_heap_used, SIZET2NUM(objspace->heap.used));

Author: Aman Gupta aman@tmm1.net
Date: Mon Mar 18 18:59:50 2013 -0700

add more stats to GC.stat

diff --git a/gc.c b/gc.c
index c49f1dd..8f458db 100644
--- a/gc.c
+++ b/gc.c
@@ -3174,18 +3174,28 @@ gcstat(int argc, VALUE *argv, VALUE self)
{
rb
objspacet *objspace = &rbobjspace;
VALUE hash;
+ sizet totalnum, livenum;
static VALUE sym
count;
static VALUE symheapused, symheaplength, symheapincrement;
- static VALUE symheaplivenum, symheapfreenum, symheapfinalnum;
+ static VALUE sym
heapobjlimit, symheaptotalnum;
+ static VALUE sym
heaplivenum, symheapemptynum, symheapfinalnum;
+ static VALUE symheapmarkednum, symheapsweepnum, symheapsweptnum;
+ static VALUE sym
islazysweeping;
static VALUE symtotalallocatedobject, symtotalfreedobject;
if (symcount == 0) {
sym
count = ID2SYM(rbinternconst("count"));
symheapused = ID2SYM(rbinternconst("heapused"));
sym
heaplength = ID2SYM(rbinternconst("heaplength"));
symheapincrement = ID2SYM(rbinternconst("heapincrement"));
+ sym
heapobjlimit = ID2SYM(rbinternconst("heapobjlimit"));
+ symheaptotalnum = ID2SYM(rbinternconst("heaptotalnum"));
sym
heaplivenum = ID2SYM(rbinternconst("heaplivenum"));
- symheapfreenum = ID2SYM(rbinternconst("heapfreenum"));
+ sym
heapemptynum = ID2SYM(rbinternconst("heapemptynum"));
symheapfinalnum = ID2SYM(rbinternconst("heapfinalnum"));
+ sym
heapmarkednum = ID2SYM(rbinternconst("heapmarkednum"));
+ symheapsweepnum = ID2SYM(rbinternconst("heapsweepnum"));
+ sym
heapsweptnum = ID2SYM(rbinternconst("heapsweptnum"));
+ symislazysweeping = ID2SYM(rbinternconst("islazysweeping"));
sym
totalallocatedobject = ID2SYM(rbinternconst("totalallocatedobject"));
symtotalfreedobject = ID2SYM(rbinternconst("totalfreedobject"));
}
@@ -3201,12 +3211,21 @@ gc
stat(int argc, VALUE *argv, VALUE self)

 rb_hash_aset(hash, sym_count, SIZET2NUM(objspace->count));
 /* implementation dependent counters */
  • totalnum = heapsused * HEAPOBJLIMIT;
  • livenum = objspacelivenum(objspace); + rbhashaset(hash, symheapused, SIZET2NUM(objspace->heap.used)); rbhashaset(hash, symheaplength, SIZET2NUM(objspace->heap.length)); rbhashaset(hash, symheap_increment, SIZET2NUM(objspace->heap.increment));
  • rbhashaset(hash, symheaplivenum, SIZET2NUM(objspacelive_num(objspace)));
  • rbhashaset(hash, symheapfreenum, SIZET2NUM(objspace->heap.sweptnum));
  • rbhashaset(hash, symheapobjlimit, SIZET2NUM(HEAPOBJ_LIMIT));
  • rbhashaset(hash, symheaptotalnum, SIZET2NUM(totalnum));
  • rbhashaset(hash, symheaplivenum, SIZET2NUM(livenum));
  • rbhashaset(hash, symheapemptynum, SIZET2NUM(totalnum - livenum)); rbhashaset(hash, symheapfinalnum, SIZET2NUM(objspace->heap.final_num));
  • rbhashaset(hash, symislazysweeping, islazy_sweeping(objspace) ? Qtrue : Qfalse);
  • rbhashaset(hash, symheapmarkednum, SIZET2NUM(objspace->heap.markednum));
  • rbhashaset(hash, symheapsweptnum, SIZET2NUM(objspace->heap.sweptnum));
  • rbhashaset(hash, symheapsweepnum, SIZET2NUM(objspace->heap.sweepnum)); rbhashaset(hash, symtotalallocatedobject, SIZET2NUM(objspace->totalallocatedobjectnum)); rbhashaset(hash, symtotalfreedobject, SIZET2NUM(objspace->totalfreedobjectnum));

History

#1 Updated by Narihiro Nakamura about 1 year ago

  • Assignee changed from Narihiro Nakamura to Koichi Sasada

ko1-san, what do you think?

#2 Updated by Koichi Sasada about 1 year ago

(2013/03/19 11:58), authorNari (Narihiro Nakamura) wrote:

ko1-san, what do you think?

(1) Performance

One concern is making it fat seems slow it down.

(2) Usage

How to use new statistics?

--
// SASADA Koichi at atdot dot net

#3 Updated by Koichi Sasada 7 months ago

  • Target version set to 2.1.0

#4 Updated by Aman Gupta 7 months ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

Also available in: Atom PDF