To explain this problem, I put all code and results.
=================================modified code===========================
static lu_mem singlestep (lua_State *L) {
global_State *g = G(L);
switch (g->gcstate) {
case GCSpause: {
g->GCmemtrav = 0; /* start to count memory traversed */
if (!isgenerational(g))
markroot(g); /* start a new collection */
/* in any case, root must be marked at this point */
lua_assert(!iswhite(obj2gco(g->mainthread))
&& !iswhite(gcvalue(&g->l_registry)));
g->gcstate = GCSpropagate;
 
; if(!g->gray)
{
fprintf(stdout, "empty gray list\n"); // ++++++++++++++++++ nothing to mark
}
return g->GCmemtrav;
}
case GCSpropagate: {
.......
}
static void generationalcollection (lua_State *L) {
global_State *g = G(L);
lu_mem est = g->GCestimate;
lu_mem ttb = gettotalbytes(g);
int tdeb = g->GCdebt;
const char *tg = "full";
if (g->GCestimate == 0) { /* signal for another major collection? */
luaC_fullgc(L, 0); /* perform a full regular collection */
g->GCestimate = gettotalbytes(g); /* update control */
}
else {
lu_mem estimate = g->GCestimate;
luaC_runti
lstate(L, ~bitmask(GCSpause)); /* run complete cycle */
luaC_runtilstate(L, bitmask(GCSpause));
//fprintf(stdout, "estimate %d/%d gettotalbytes(g) (estimate / 100) * g->gcmajorinc %d/%d\n", estimate, g->GCestimate, gettotalbytes(g), (estimate / 100) * g->gcmajorinc);
if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc)
{
fprintf(stdout, "total bytes > estimate * gcmajorinc / estimate\n"); // +++++++++++++ indicate full gc triggered
g->GCestimate = 0; /* signal for a major collection */
}
tg = "gen";
}
luaE_setdebt(g, stddebt(g));
fprintf(stdout, "##%6s estimate %8u -> %8u totalb %8u (%+d) debt %+8d -> %+8d\n", tg,
est, g->GCestimate,
gettotalbytes
(g), gettotalbytes(g) - ttb,
tdeb, g->GCdebt);
}
======================== lua script =======================================
local SQSIZE, NSIZE, PAUSE, STEPMUL = ...
collectgarbage "stop"
local function g()
local ret = {}
for i=1,SQSIZE do ret[i] = {a=1} end
return ret
end
b = {}
for i=1,SQSIZE do b[i]=g() end
t = {}
collectgarbage "collect"
collectgarbage "collect"
collectgarbage("setpause", PAUSE)
collectgarbage("setstepmul", STEPMUL)
collectgarbage("restart")
collectgarbage "generational"
print("---------")
local maxalloc = 0
local n = 0
for i=1,1000000 do
local s = "n" .. i
t[n] = s
if n == NSIZE then n = 0 else n = n + 1 end
local ma = collectgarbage "count"
if ma > maxa
lloc then maxalloc = ma end
end
print("OK, done, maxalloc = ", maxalloc, ", #t = ", #t)
collectgarbage "collect"
collectgarbage "collect"
============================= results ==========================================
case 1:D:\Sources\lua\lua-5.2.1>lua\Debug\lua.exe gengc-test.lua 500 100 10 0 >out
## gen estimate 16083903 -> 16093748 totalb 16083943 (+0) debt +40 -> -804190
---------
empty gray list
## gen estimate 16093748 -> 0 totalb 16557371 (-330767) debt +5 -> -827860
## full estimate 0 -> 17009496 totalb 17009496 (-375762) debt +27 -> -850470
## gen estimate 17009496 -> 17385317 totalb 17636208 (-223784) debt&
nbsp; +26 -> -881810
empty gray list
## gen estimate 17385317 -> 0 totalb 17998590 (-608412) debt +88984 -> -899920
## full estimate 0 -> 18324161 totalb 18324161 (-574390) debt +41 -> -916200
## gen estimate 18324161 -> 18663660 totalb 19176695 (-63668) debt +2 -> -958830
empty gray list
## gen estimate 18663660 -> 0 totalb 19666957 (-468588) debt +20 -> -983340
## full estimate 0 -> 20168926 totalb 20168926 (-481381) debt +10 -> -1008440
## gen estimate 20168926 -> 19913819 totalb 20426854 (-771909) de
bt +21397 -> -1021340
empty gray list
## gen estimate 19913819 -> 0 totalb 20680870 (-767361) debt +37 -> -1034040
## full estimate 0 -> 22263238 totalb 22263238 (-9939) debt +558267 -> -1113160
## gen estimate 22263238 -> 21794115 totalb 22831438 (-544965) debt +5 -> -1141570
empty gray list
## gen estimate 21794115 -> 0 totalb 23414566 (-558472) debt +30 -> -1170720
## full estimate 0 -> 24011974 totalb 24011974 (-573347) debt +35 -> -1200590
## gen estimate 24011974 -> 23587515 totalb 24624838 (-587768) debt +42 ->
-1231240
empty gray list
## gen estimate 23587515 -> 0 totalb 25014502 (-1421645) debt +580069 -> -1250720
## full estimate 0 -> 25208734 totalb 25208734 (-1235546) debt +179058 -> -1260430
## gen estimate 25208734 -> 24279387 totalb 25316710 (-1152493) debt +39 -> -1265830
empty gray list
## gen estimate 24279387 -> 0 totalb 28555102 (-88444) debt +2061006 -> -1427750
## full estimate 0 -> 29283742 totalb 29283742 (-699111) debt +1 -> -1464180
## gen estimate 29283742 -> 27945299 totalb 30031198 (-716752) debt +28 -> -1501550
empty gray list
## gen estimate 27945299 -
> 0 totalb 30798142 (-734629) debt +23 -> -1539900
## full estimate 0 -> 31584070 totalb 31584070 (-754012) debt +40 -> -1579200
## gen estimate 31584070 -> 30304355 totalb 32390254 (-773033) debt +17 -> -1619510
empty gray list
## gen estimate 30304355 -> 0 totalb 33217438 (-792359) debt +33 -> -1660870
## full estimate 0 -> 34028782 totalb 34028782 (-2875521) debt +2025995 -> -1701430
## gen estimate 34028782 -> 32348771 totalb 34434670 (-2486568) debt +1191026 -> -1721730
empty gray list
## gen estimate 32348771 -> 0 totalb 346
38022 (-2291672) debt +773294 -> -1731900
## full estimate 0 -> 34739086 totalb 34739086 (-2194836) debt +564000 -> -1736950
## gen estimate 34739086 -> 32703923 totalb 34789822 (-2146214) debt +460000 -> -1739490
empty gray list
## gen estimate 32703923 -> 0 totalb 34815598 (-2121495) debt +407781 -> -1740770
## full estimate 0 -> 34827862 totalb 34827862 (-2109736) debt +381230 -> -1741390
## gen estimate 34827862 -> 32748299 totalb 34834198 (-2103664) debt +368610 -> -1741700
empty gray list
## gen estimate 32748299 -> 0 totalb 34837774 (-2100220) debt +362096 -> -1741880
## full estimate 0 ->
; 34838950 totalb 34838950 (-2099110) debt +358406 -> -1741940
## gen estimate 34838950 -> 32753843 totalb 34839742 (-2098351) debt +357203 -> -1741980
empty gray list
## gen estimate 32753843 -> 0 totalb 34840558 (-2097575) debt +356411 -> -1742020
## full estimate 0 -> 34840342 totalb 34840342 (-2097776) debt +355540 -> -1742010
## gen estimate 34840342 -> 32754539 totalb 34840438 (-2097684) debt +355770 -> -1742020
empty gray list
## gen estimate 32754539 -> 0 totalb 34840894 (-2097230) debt +355666 -> -1742040
## full estimate 0 -> 36937662 totalb 36937662 (-463) debt +355191 -> -1846880
## gen estimate 36937662 -> 36954555 to
talb 41137606 (-5845) debt +2358909 -> -2056880
empty gray list
## gen estimate 36954555 -> 0 totalb 42188134 (-1006397) debt +45 -> -2109400
## full estimate 0 -> 43264870 totalb 43264870 (-1032703) debt +39 -> -2163240
## gen estimate 43264870 -> 40186251 totalb 44369302 (-1058854) debt +46 -> -2218460
empty gray list
## gen estimate 40186251 -> 0 totalb 45502318 (-1085448) debt +4 -> -2275110
## full estimate 0 -> 46663654 totalb 46663654 (-1113778) debt +4 -> -2333180
## gen estimate 46663654 -> 43671795 totalb 47854846 (-1141999
) debt +11 -> -2392740
empty gray list
## gen estimate 43671795 -> 0 totalb 49076878 (-1170755) debt +47 -> -2453840
## full estimate 0 -> 50329486 totalb 50329486 (-1201247) debt +15 -> -2516470
## gen estimate 50329486 -> 47431227 totalb 51614278 (-1231699) debt +21 -> -2580710
OK, done, maxalloc = 52203.346679688 , #t = 999999
case 2:D:\Sources\lua\lua-5.2.1>lua\Debug\lua.exe gengc-test.lua 500 100 100 0 >out2
## gen estimate 16083884 -> 16093729 totalb 16083924 (+0) debt +40 -> -8041900
---------
empty gray list
## gen e
stimate 16093729 -> 0 totalb 21211963 (-3949497) debt +1035636 -> -10605900
## full estimate 0 -> 28680147 totalb 28680147 (-3137751) debt +35 -> -14340000
## gen estimate 28680147 -> 36954536 totalb 41137587 (-5909508) debt +4026948 -> -20568700
empty gray list
## gen estimate 36954536 -> 0 totalb 49499187 (-12207145) debt +45 -> -24749500
OK, done, maxalloc = 60260.043945313 , #t = 999999
========================= conclusion ========================================
We expect to see the following code, but not.
"total bytes > estimate * gcmajorinc / estimate\n"In the loop of test code, all operation is to put strings into t
able. Lua VM's write barrier just put table to gray again list, and put nothing to gray list. So in next gc cycle, g->GCestimate = 0. And it trigger a full gc, not in expected manner.
At 2013-01-08 00:29:34,"Roberto Ierusalimschy" <roberto@inf.puc-rio.br> wrote:
>>
>> I run the test code on http://lua-users.org/lists/lua-l/2010-06/msg00001.html.
>
>What parameters did you give to the script? Can you simplify it without
>removing the problem?
>
>-- Roberto
>