lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Lua 5.2.4
My program is a busy MMORPG(massively multiplayer online role-playing
game) server,
I hope GC start a new cycle as soon as possible, so I set "gcpause" to
90 according to
I found that the progress stuck for a few seconds at the end of sweep
state (before propagate state),
the CPU's usage is quite high(99.9%).

The reason for this is that at the end of gc sweep, gcstate switch to pause,
[F] g->GCDebt = totalbytes - E * P / 100,
E:=g->GCestimate (memory traversed by the propagate state)
P:=g->gcpause (set by collectgarbage("setpause"))
Because traversetable() doesn't calculate the inner GCObject and nest
table's size,
so E is much less than totalbytes.
e.g. when there are 10k players online, the memory usage of my program
is quite high:
totalbytes:=18.5G,   E:=9.5G,  P:=90
according to formula [F], g->GCDebt is 9.95G, a big number.

In lgc.c,  function incstep()
1139 static void incstep (lua_State *L) {
1140   global_State *g = G(L);
1141   l_mem debt = g->GCdebt;
1147   do {  /* always perform at least one single step */
1148       lu_mem work = singlestep(L);  /* do some work */
1149       debt -= work;
1150   } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);

The while loop  call singlestep() until debt decrease to -GCSTEPSIZE.
When the g->GCDebt is big, singlestep() will be called for many many times,
and all the players cann't operation before the while loop end.
I hope g->GCDebt is small(near zero) at the end of each gc cycle,
but I think it's a little difficult to estimate a appropriate P.
My solution is add a runtime option "nopause",
when "nopause" is non-zero, set g->GCDebt to 0,
so the GC will start a new cycle immediately.
1151   if (g->gcstate == GCSpause) {
1152     if (g->nopuase)
1153       luaE_setdebt(g, 0);
1154     else
1155       setpause(g, g->GCestimate);  /* pause until next cycle */
1156   } else {

Nowadays, Lua is popular in MMORPG server program.
This kind of program is expected to to hold as many online players as
possible, so the CPU and memory usage is high.
I think this kind of program doesn't need pause state, because it will
increase the memory usage.
Once the memory usage increase , the total execute time of atomic()
function becomes long,
and the response time of player's operation becomes long.
I think it may be a little difficult to estimate a appropriate P for
formula [F],
when the "totalbytes" and "E" is big and mutable.
So I suggest adding a "nopause" option to collectgarbage() in future version.


Best Regards
John Wei