[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Why gc sweepstep() doesn't return the real free bytes?
- From: 张伟智 <robotk@...>
- Date: Fri, 18 Dec 2015 21:33:43 +0800 (CST)
Lua version 5.3.0
In each gc step,
luaC_step() call singlestep() in while loop until debt reduce to -GCSTEPSIZE,
singlestep() return the bytes haved processed:
1.in propagate state, it return the bytes traversed(marked);
2.in sweep state, it return a estimate value: GCSWEEPMAX * GCSWEEPCOST;
In a 64bits Debian Linux system, GCSWEEPCOST is 7 bytes,
which is much smaller than any kind GCObject(TString, Udata, ...).
After each call to singlestep(), debt reduce GCSWEEPMAX * GCSWEEPCOST,
until to -GCSTEPSIZE.
So the GCSWEEPCOST much smaller,
the times of execute singlestep() is much more,
i.e., the speed of sweep(free) is much faster;
In our program, collectgarbage("count") is 10G at the end of propagate state,
while gc switch to sweep state, gc system free 5G bytes in only 30 seconds,
and the usage of CPU is 99.9% during the whole 30 seconds sweep state;
If I adjust GCSWEEPCOST to a larger value,
the time of sweep state becomes long,
and CPU's usage becomes lower.
But it is a little difficult to adjust GCSWEEPCOST to a fit value;
I am curious about why sweepstep() doesn't return the real free bytes, i.e, olddebt - g->GCdebt ?
Thanks.
1011 static lu_mem sweepstep (lua_State *L, global_State *g,
1012 int nextstate, GCObject **nextlist) {
1013 if (g->sweepgc) {
1014 l_mem olddebt = g->GCdebt;
1015 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
1016 g->GCestimate += g->GCdebt - olddebt; /* update estimate */
1017 if (g->sweepgc) /* is there still something to sweep? */
1018 return (GCSWEEPMAX * GCSWEEPCOST);
1019 }
...
}
1109 void luaC_step (lua_State *L) {
1110 global_State *g = G(L);
1111 l_mem debt = getdebt(g); /* GC deficit (be paid now) */
1112 if (!g->gcrunning) { /* not running? */
1113 luaE_setdebt(g, -GCSTEPSIZE * 10); /* avoid being called too often */
1114 return;
1115 }
1116 do { /* repeat until pause or enough "credit" (negative debt) */
1117 lu_mem work = singlestep(L); /* perform one single step */
1118 debt -= work;
1119 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
1120 if (g->gcstate == GCSpause)
1121 setpause(g); /* pause until next cycle */
1122 else {
1123 debt = (debt / g->gcstepmul) * STEPMULADJ; /* convert 'work units' to Kb */
1124 luaE_setdebt(g, debt);
1125 runafewfinalizers(L);
1126 }
1127 }
Best Regards
John Wei