mirror of
https://github.com/lua/lua.git
synced 2024-11-23 10:13:50 +08:00
First criteria for shifts minor<->major
This commit is contained in:
parent
789e7acdea
commit
925fe8a0f2
25
lapi.c
25
lapi.c
@ -1204,26 +1204,29 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||
break;
|
||||
}
|
||||
case LUA_GCGEN: {
|
||||
unsigned int minormul = va_arg(argp, unsigned int);
|
||||
unsigned int majormul = va_arg(argp, unsigned int);
|
||||
int minormul = va_arg(argp, int);
|
||||
int minormajor = va_arg(argp, int);
|
||||
int majorminor = va_arg(argp, int);
|
||||
res = (g->gckind == KGC_INC) ? LUA_GCINC : LUA_GCGEN;
|
||||
if (minormul != 0)
|
||||
if (minormul >= 0)
|
||||
setgcparam(g, genminormul, minormul);
|
||||
if (majormul != 0)
|
||||
setgcparam(g, genmajormul, majormul);
|
||||
if (minormajor >= 0)
|
||||
setgcparam(g, minormajor, minormajor);
|
||||
if (majorminor >= 0)
|
||||
setgcparam(g, majorminor, majorminor);
|
||||
luaC_changemode(L, KGC_GENMINOR);
|
||||
break;
|
||||
}
|
||||
case LUA_GCINC: {
|
||||
unsigned int pause = va_arg(argp, unsigned int);
|
||||
unsigned int stepmul = va_arg(argp, unsigned int);
|
||||
unsigned int stepsize = va_arg(argp, unsigned int);
|
||||
int pause = va_arg(argp, int);
|
||||
int stepmul = va_arg(argp, int);
|
||||
int stepsize = va_arg(argp, int);
|
||||
res = (g->gckind == KGC_INC) ? LUA_GCINC : LUA_GCGEN;
|
||||
if (pause != 0)
|
||||
if (pause >= 0)
|
||||
setgcparam(g, gcpause, pause);
|
||||
if (stepmul != 0)
|
||||
if (stepmul >= 0)
|
||||
setgcparam(g, gcstepmul, stepmul);
|
||||
if (stepsize != 0)
|
||||
if (stepsize >= 0)
|
||||
g->gcstepsize = (stepsize <= log2maxs(l_obj)) ? stepsize
|
||||
: log2maxs(l_obj);
|
||||
luaC_changemode(L, KGC_INC);
|
||||
|
13
lbaselib.c
13
lbaselib.c
@ -224,14 +224,15 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
case LUA_GCGEN: {
|
||||
int minormul = (int)luaL_optinteger(L, 2, 0);
|
||||
int majormul = (int)luaL_optinteger(L, 3, 0);
|
||||
return pushmode(L, lua_gc(L, o, minormul, majormul));
|
||||
int minormul = (int)luaL_optinteger(L, 2, -1);
|
||||
int majorminor = (int)luaL_optinteger(L, 3, -1);
|
||||
int minormajor = (int)luaL_optinteger(L, 4, -1);
|
||||
return pushmode(L, lua_gc(L, o, minormul, majorminor, minormajor));
|
||||
}
|
||||
case LUA_GCINC: {
|
||||
int pause = (int)luaL_optinteger(L, 2, 0);
|
||||
int stepmul = (int)luaL_optinteger(L, 3, 0);
|
||||
int stepsize = (int)luaL_optinteger(L, 4, 0);
|
||||
int pause = (int)luaL_optinteger(L, 2, -1);
|
||||
int stepmul = (int)luaL_optinteger(L, 3, -1);
|
||||
int stepsize = (int)luaL_optinteger(L, 4, -1);
|
||||
return pushmode(L, lua_gc(L, o, pause, stepmul, stepsize));
|
||||
}
|
||||
default: {
|
||||
|
81
lgc.c
81
lgc.c
@ -1205,20 +1205,21 @@ static void correctgraylists (global_State *g) {
|
||||
/*
|
||||
** Mark black 'OLD1' objects when starting a new young collection.
|
||||
** Gray objects are already in some gray list, and so will be visited in
|
||||
** the atomic step. The counter 'GCmajorminor' keeps how many objects to
|
||||
** become old before a major collection.
|
||||
** the atomic step. Returns the number of objects that became old.
|
||||
*/
|
||||
static void markold (global_State *g, GCObject *from, GCObject *to) {
|
||||
static l_obj markold (global_State *g, GCObject *from, GCObject *to) {
|
||||
GCObject *p;
|
||||
l_obj count = 0;
|
||||
for (p = from; p != to; p = p->next) {
|
||||
if (getage(p) == G_OLD1) {
|
||||
lua_assert(!iswhite(p));
|
||||
setage(p, G_OLD); /* now they are old */
|
||||
g->GCmajorminor--; /* one more old object */
|
||||
count++; /* one more old object */
|
||||
if (isblack(p))
|
||||
reallymarkobject(g, p);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@ -1240,7 +1241,7 @@ static void finishgencycle (lua_State *L, global_State *g) {
|
||||
*/
|
||||
static void atomic2major (lua_State *L, global_State *g) {
|
||||
l_obj stepsize = cast(l_obj, 1) << g->gcstepsize;
|
||||
g->GCmajorminor = gettotalobjs(g);
|
||||
g->GCmajorminor = g->marked; /* number of live objects */
|
||||
g->gckind = KGC_GENMAJOR;
|
||||
g->reallyold = g->old1 = g->survival = NULL;
|
||||
g->finobjrold = g->finobjold1 = g->finobjsur = NULL;
|
||||
@ -1249,30 +1250,54 @@ static void atomic2major (lua_State *L, global_State *g) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Decide whether to shift to major mode. It tests two conditions:
|
||||
** 1) Whether the number of added old objects in this collection is more
|
||||
** than half the number of new objects. ("step" is the number of objects
|
||||
** created between minor collections. Except for forward barriers, it
|
||||
** is the maximum number of objects that can become old in each minor
|
||||
** collection.)
|
||||
** 2) Whether the accumulated number of added old objects is larger
|
||||
** than 'minormajor'% of the number of lived objects after the last
|
||||
** major collection. (That percentage is computed in 'limit'.)
|
||||
*/
|
||||
static int checkminormajor (lua_State *L, global_State *g, l_obj addedold1) {
|
||||
l_obj step = applygcparam(g, genminormul, g->GCmajorminor);
|
||||
l_obj limit = applygcparam(g, minormajor, g->GCmajorminor);
|
||||
//printf("-> major? %ld %ld %ld %ld (%ld)\n", g->marked, limit, step, addedold1, gettotalobjs(g));
|
||||
if (addedold1 >= (step >> 1) || g->marked >= limit) {
|
||||
atomic2major(L, g); /* go to major mode */
|
||||
return 1;
|
||||
}
|
||||
return 0; /* stay in minor mode */
|
||||
}
|
||||
|
||||
/*
|
||||
** Does a young collection. First, mark 'OLD1' objects. Then does the
|
||||
** atomic step. Then, check whether to continue in minor mode. If so,
|
||||
** sweep all lists and advance pointers. Finally, finish the collection.
|
||||
*/
|
||||
static void youngcollection (lua_State *L, global_State *g) {
|
||||
l_obj addedold1 = 0;
|
||||
l_obj marked = g->marked; /* preserve 'g->marked' */
|
||||
GCObject **psurvival; /* to point to first non-dead survival object */
|
||||
GCObject *dummy; /* dummy out parameter to 'sweepgen' */
|
||||
lua_assert(g->gcstate == GCSpropagate);
|
||||
g->marked = 0;
|
||||
if (g->firstold1) { /* are there regular OLD1 objects? */
|
||||
markold(g, g->firstold1, g->reallyold); /* mark them */
|
||||
addedold1 += markold(g, g->firstold1, g->reallyold); /* mark them */
|
||||
g->firstold1 = NULL; /* no more OLD1 objects (for now) */
|
||||
}
|
||||
markold(g, g->finobj, g->finobjrold);
|
||||
markold(g, g->tobefnz, NULL);
|
||||
addedold1 += markold(g, g->finobj, g->finobjrold);
|
||||
addedold1 += markold(g, g->tobefnz, NULL);
|
||||
|
||||
atomic(L);
|
||||
atomic(L); /* will lose 'g->marked' */
|
||||
|
||||
/* keep total number of added old1 objects */
|
||||
g->marked = marked + addedold1;
|
||||
|
||||
/* decide whether to shift to major mode */
|
||||
if (g->GCmajorminor <= 0) { /* ?? */
|
||||
atomic2major(L, g); /* go to major mode */
|
||||
if (checkminormajor(L, g, addedold1))
|
||||
return; /* nothing else to be done here */
|
||||
}
|
||||
|
||||
/* sweep nursery and get a pointer to its last live element */
|
||||
g->gcstate = GCSswpallgc;
|
||||
@ -1319,7 +1344,8 @@ static void atomic2gen (lua_State *L, global_State *g) {
|
||||
sweep2old(L, &g->tobefnz);
|
||||
|
||||
g->gckind = KGC_GENMINOR;
|
||||
g->GCmajorminor = applygcparam(g, genmajormul, g->marked);
|
||||
g->GCmajorminor = g->marked; /* "base" for number of objects */
|
||||
g->marked = 0; /* to count the number of added old1 objects */
|
||||
finishgencycle(L, g);
|
||||
}
|
||||
|
||||
@ -1329,7 +1355,7 @@ static void atomic2gen (lua_State *L, global_State *g) {
|
||||
** total number of objects grows 'genminormul'%.
|
||||
*/
|
||||
static void setminordebt (global_State *g) {
|
||||
luaE_setdebt(g, applygcparam(g, genminormul, gettotalobjs(g)));
|
||||
luaE_setdebt(g, applygcparam(g, genminormul, g->GCmajorminor));
|
||||
}
|
||||
|
||||
|
||||
@ -1369,13 +1395,11 @@ static void enterinc (global_State *g) {
|
||||
*/
|
||||
void luaC_changemode (lua_State *L, int newmode) {
|
||||
global_State *g = G(L);
|
||||
if (g->gckind == KGC_GENMAJOR) /* doing major collections? */
|
||||
g->gckind = KGC_INC; /* already incremental but in name */
|
||||
if (newmode != g->gckind) { /* does it need to change? */
|
||||
if (newmode == KGC_INC) { /* entering incremental mode? */
|
||||
if (g->gckind == KGC_GENMAJOR)
|
||||
g->gckind = KGC_INC; /* already incremental but in name */
|
||||
else
|
||||
enterinc(g); /* entering incremental mode */
|
||||
}
|
||||
if (newmode == KGC_INC) /* entering incremental mode? */
|
||||
enterinc(g); /* entering incremental mode */
|
||||
else {
|
||||
lua_assert(newmode == KGC_GENMINOR);
|
||||
entergen(L, g);
|
||||
@ -1396,16 +1420,24 @@ static void fullgen (lua_State *L, global_State *g) {
|
||||
/*
|
||||
** After an atomic incremental step from a major collection,
|
||||
** check whether collector could return to minor collections.
|
||||
** It checks whether the number of objects 'tobecollected'
|
||||
** is greater than 'majorminor'% of the number of objects added
|
||||
** since the last collection ('addedobjs').
|
||||
*/
|
||||
static int checkmajorminor (lua_State *L, global_State *g) {
|
||||
if (g->gckind == KGC_GENMAJOR) {
|
||||
l_obj numobjs = gettotalobjs(g); /* current count */
|
||||
if (g->marked < numobjs - (numobjs >> 2)) { /* ?? */
|
||||
l_obj numobjs = gettotalobjs(g);
|
||||
l_obj addedobjs = numobjs - g->GCmajorminor;
|
||||
l_obj limit = applygcparam(g, majorminor, addedobjs);
|
||||
l_obj tobecollected = numobjs - g->marked;
|
||||
//printf("-> minor? %ld %ld %ld\n", tobecollected, limit, numobjs);
|
||||
if (tobecollected > limit) {
|
||||
atomic2gen(L, g); /* return to generational mode */
|
||||
setminordebt(g);
|
||||
return 0; /* exit incremental collection */
|
||||
}
|
||||
}
|
||||
g->GCmajorminor = g->marked; /* prepare for next collection */
|
||||
return 1; /* stay doing incremental collections */
|
||||
}
|
||||
|
||||
@ -1634,8 +1666,6 @@ void luaC_step (lua_State *L) {
|
||||
if (!gcrunning(g)) /* not running? */
|
||||
luaE_setdebt(g, 2000);
|
||||
else {
|
||||
//printf("> step: %d %d %ld %ld -> ", g->gckind, g->gcstate, gettotalobjs(g), g->GCdebt);
|
||||
|
||||
switch (g->gckind) {
|
||||
case KGC_INC: case KGC_GENMAJOR:
|
||||
incstep(L, g);
|
||||
@ -1645,7 +1675,6 @@ void luaC_step (lua_State *L) {
|
||||
setminordebt(g);
|
||||
break;
|
||||
}
|
||||
//printf("%d %d %ld %ld\n", g->gckind, g->gcstate, gettotalobjs(g), g->GCdebt);
|
||||
}
|
||||
}
|
||||
|
||||
|
48
lgc.h
48
lgc.h
@ -161,10 +161,24 @@
|
||||
|
||||
/* Default Values for GC parameters */
|
||||
|
||||
/* generational */
|
||||
/*
|
||||
** Minor collections will shift to major ones after LUAI_MINORMAJOR%
|
||||
** objects become old.
|
||||
*/
|
||||
#define LUAI_MINORMAJOR 100
|
||||
|
||||
/*
|
||||
** Major collections will shift to minor ones after a collection
|
||||
** collects at least LUAI_MAJORMINOR% of the new objects.
|
||||
*/
|
||||
#define LUAI_MAJORMINOR 80
|
||||
|
||||
/*
|
||||
** A young (minor) collection will run after creating LUAI_GENMINORMUL%
|
||||
** new objects.
|
||||
*/
|
||||
#define LUAI_GENMINORMUL 20
|
||||
|
||||
#define LUAI_GENMAJORMUL 100 /* major multiplier */
|
||||
#define LUAI_GENMINORMUL 20 /* minor multiplier */
|
||||
|
||||
/* incremental */
|
||||
|
||||
@ -187,27 +201,17 @@
|
||||
|
||||
/*
|
||||
** Macros to set and apply GC parameters. GC parameters are given in
|
||||
** percentage points, but are stored as lu_byte. To reduce their
|
||||
** values and avoid repeated divisions by 100, these macros store
|
||||
** the original parameter multiplied by 2^n and divided by 100.
|
||||
** To apply them, the value is divided by 2^n (a shift) and then
|
||||
** multiplied by the stored parameter, yielding
|
||||
** value / 2^n * (original parameter * 2^n / 100), or approximately
|
||||
** (value * original parameter / 100).
|
||||
**
|
||||
** For most parameters, which are typically larger than 100%, 2^n is
|
||||
** 16 (2^4), allowing maximum values up to ~1500%, with a granularity
|
||||
** of ~6%. For the minor multiplier, which is typically smaller,
|
||||
** 2^n is 64 (2^6) to allow more precision. In that case, the maximum
|
||||
** value is ~400%, with a granularity of ~1.5%.
|
||||
** percentage points, but are stored as lu_byte. To avoid repeated
|
||||
** divisions by 100, these macros store the original parameter
|
||||
** multiplied by 128 and divided by 100. To apply them, if it first
|
||||
** divides the value by 128 it may lose precision; if it first
|
||||
** multiplies by the parameter, it may overflow. So, it first divides
|
||||
** by 32, then multiply by the parameter, and then divides the result by
|
||||
** 4.
|
||||
*/
|
||||
#define gcparamshift(p) \
|
||||
(offsetof(global_State, p) == offsetof(global_State, genminormul) ? 6 : 4)
|
||||
|
||||
#define setgcparam(g,p,v) \
|
||||
(g->p = (cast_uint(v) << gcparamshift(p)) / 100u)
|
||||
#define applygcparam(g,p,v) (((v) >> gcparamshift(p)) * g->p)
|
||||
|
||||
#define setgcparam(g,p,v) (g->gcp##p = (cast_uint(v) << 7) / 100u)
|
||||
#define applygcparam(g,p,v) ((((v) >> 5) * g->gcp##p) >> 2)
|
||||
|
||||
|
||||
/*
|
||||
|
3
lstate.c
3
lstate.c
@ -368,8 +368,9 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud, unsigned int seed) {
|
||||
setgcparam(g, gcpause, LUAI_GCPAUSE);
|
||||
setgcparam(g, gcstepmul, LUAI_GCMUL);
|
||||
g->gcstepsize = LUAI_GCSTEPSIZE;
|
||||
setgcparam(g, genmajormul, LUAI_GENMAJORMUL);
|
||||
setgcparam(g, genminormul, LUAI_GENMINORMUL);
|
||||
setgcparam(g, minormajor, LUAI_MINORMAJOR);
|
||||
setgcparam(g, majorminor, LUAI_MAJORMINOR);
|
||||
for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
|
||||
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
|
||||
/* memory allocation error: free partial state */
|
||||
|
9
lstate.h
9
lstate.h
@ -264,16 +264,17 @@ typedef struct global_State {
|
||||
TValue l_registry;
|
||||
TValue nilvalue; /* a nil value */
|
||||
unsigned int seed; /* randomized seed for hashes */
|
||||
unsigned short gcpgenminormul; /* control minor generational collections */
|
||||
unsigned short gcpmajorminor; /* control shift major->minor */
|
||||
unsigned short gcpminormajor; /* control shift minor->major */
|
||||
unsigned short gcpgcpause; /* size of pause between successive GCs */
|
||||
unsigned short gcpgcstepmul; /* GC "speed" */
|
||||
lu_byte currentwhite;
|
||||
lu_byte gcstate; /* state of garbage collector */
|
||||
lu_byte gckind; /* kind of GC running */
|
||||
lu_byte gcstopem; /* stops emergency collections */
|
||||
lu_byte genminormul; /* control for minor generational collections */
|
||||
lu_byte genmajormul; /* control for major generational collections */
|
||||
lu_byte gcstp; /* control whether GC is running */
|
||||
lu_byte gcemergency; /* true if this is an emergency collection */
|
||||
lu_byte gcpause; /* size of pause between successive GCs */
|
||||
lu_byte gcstepmul; /* GC "speed" */
|
||||
lu_byte gcstepsize; /* (log2 of) GC granularity */
|
||||
GCObject *allgc; /* list of all collectable objects */
|
||||
GCObject **sweepgc; /* current position of sweep in list */
|
||||
|
2
lua.c
2
lua.c
@ -646,7 +646,7 @@ static int pmain (lua_State *L) {
|
||||
luai_openlibs(L); /* open standard libraries */
|
||||
createargtable(L, argv, argc, script); /* create table 'arg' */
|
||||
lua_gc(L, LUA_GCRESTART); /* start GC... */
|
||||
lua_gc(L, LUA_GCGEN, 0, 0); /* ...in generational mode */
|
||||
lua_gc(L, LUA_GCGEN, -1, -1, -1); /* ...in generational mode */
|
||||
if (!(args & has_E)) { /* no option '-E'? */
|
||||
if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */
|
||||
return 0; /* error running LUA_INIT */
|
||||
|
132
manual/manual.of
132
manual/manual.of
@ -621,7 +621,8 @@ that is inaccessible from Lua.
|
||||
another live object refer to the object.)
|
||||
Because Lua has no knowledge about @N{C code},
|
||||
it never collects objects accessible through the registry @see{registry},
|
||||
which includes the global environment @see{globalenv}.
|
||||
which includes the global environment @see{globalenv} and
|
||||
the main thread.
|
||||
|
||||
|
||||
The garbage collector (GC) in Lua can work in two modes:
|
||||
@ -638,8 +639,8 @@ therefore, optimal settings are also non-portable.
|
||||
You can change the GC mode and parameters by calling
|
||||
@Lid{lua_gc} @N{in C}
|
||||
or @Lid{collectgarbage} in Lua.
|
||||
You can also use these functions to control
|
||||
the collector directly (e.g., to stop and restart it).
|
||||
You can also use these functions to control the collector directly,
|
||||
for instance to stop or restart it.
|
||||
|
||||
}
|
||||
|
||||
@ -656,39 +657,36 @@ and the @def{garbage-collector step size}.
|
||||
|
||||
The garbage-collector pause
|
||||
controls how long the collector waits before starting a new cycle.
|
||||
The collector starts a new cycle when the use of memory
|
||||
hits @M{n%} of the use after the previous collection.
|
||||
The collector starts a new cycle when the number of objects
|
||||
hits @M{n%} of the total after the previous collection.
|
||||
Larger values make the collector less aggressive.
|
||||
Values equal to or less than 100 mean the collector will not wait to
|
||||
start a new cycle.
|
||||
A value of 200 means that the collector waits for the total memory in use
|
||||
to double before starting a new cycle.
|
||||
A value of 200 means that the collector waits for
|
||||
the total number of objects to double before starting a new cycle.
|
||||
The default value is 200; the maximum value is 1000.
|
||||
|
||||
The garbage-collector step multiplier
|
||||
controls the speed of the collector relative to
|
||||
memory allocation,
|
||||
object creation,
|
||||
that is,
|
||||
how many elements it marks or sweeps for each
|
||||
kilobyte of memory allocated.
|
||||
Larger values make the collector more aggressive but also increase
|
||||
the size of each incremental step.
|
||||
You should not use values less than 100,
|
||||
because they make the collector too slow and
|
||||
can result in the collector never finishing a cycle.
|
||||
The default value is 100; the maximum value is 1000.
|
||||
how many objects it marks or sweeps for each object created.
|
||||
Larger values make the collector more aggressive.
|
||||
Beware that values too small can
|
||||
make the collector too slow to ever finish a cycle.
|
||||
The default value is 300; the maximum value is 1000.
|
||||
|
||||
The garbage-collector step size controls the
|
||||
size of each incremental step,
|
||||
specifically how many bytes the interpreter allocates
|
||||
specifically how many objects the interpreter creates
|
||||
before performing a step.
|
||||
This parameter is logarithmic:
|
||||
A value of @M{n} means the interpreter will allocate @M{2@sp{n}}
|
||||
bytes between steps and perform equivalent work during the step.
|
||||
A value of @M{n} means the interpreter will create @M{2@sp{n}}
|
||||
objects between steps and perform equivalent work during the step.
|
||||
A large value (e.g., 60) makes the collector a stop-the-world
|
||||
(non-incremental) collector.
|
||||
The default value is 13,
|
||||
which means steps of approximately @N{8 Kbytes}.
|
||||
The default value is 8,
|
||||
which means steps of approximately @N{256 objects}.
|
||||
|
||||
}
|
||||
|
||||
@ -697,31 +695,44 @@ which means steps of approximately @N{8 Kbytes}.
|
||||
In generational mode,
|
||||
the collector does frequent @emph{minor} collections,
|
||||
which traverses only objects recently created.
|
||||
If after a minor collection the use of memory is still above a limit,
|
||||
the collector does a stop-the-world @emph{major} collection,
|
||||
If after a minor collection the number of objects is above a limit,
|
||||
the collector shifts to a @emph{major} collection,
|
||||
which traverses all objects.
|
||||
The generational mode uses two parameters:
|
||||
the @def{minor multiplier} and the @def{the major multiplier}.
|
||||
The collector will then stay doing major collections until
|
||||
it detects that the program is generating enough garbage to justify
|
||||
going back to minor collections.
|
||||
|
||||
The generational mode uses three parameters:
|
||||
the @def{minor multiplier}, the @def{minor-major multiplier},
|
||||
and the @def{major-minor multiplier}.
|
||||
|
||||
The minor multiplier controls the frequency of minor collections.
|
||||
For a minor multiplier @M{x},
|
||||
a new minor collection will be done when memory
|
||||
grows @M{x%} larger than the memory in use after the previous major
|
||||
collection.
|
||||
a new minor collection will be done when the number of objects
|
||||
grows @M{x%} larger than the number in use just after the last collection.
|
||||
For instance, for a multiplier of 20,
|
||||
the collector will do a minor collection when the use of memory
|
||||
gets 20% larger than the use after the previous major collection.
|
||||
The default value is 20; the maximum value is 200.
|
||||
the collector will do a minor collection when the number of objects
|
||||
gets 20% larger than the total after the last major collection.
|
||||
The default value is 20.
|
||||
|
||||
The major multiplier controls the frequency of major collections.
|
||||
For a major multiplier @M{x},
|
||||
a new major collection will be done when memory
|
||||
grows @M{x%} larger than the memory in use after the previous major
|
||||
collection.
|
||||
The minor-major multiplier controls the shift to major collections.
|
||||
For a multiplier @M{x},
|
||||
the collector will shift to a major collection
|
||||
when the number of old objects grows @M{x%} larger
|
||||
than the total after the previous major collection.
|
||||
For instance, for a multiplier of 100,
|
||||
the collector will do a major collection when the use of memory
|
||||
gets larger than twice the use after the previous collection.
|
||||
The default value is 100; the maximum value is 1000.
|
||||
the collector will do a major collection when the number of old objects
|
||||
gets larger than twice the total after the previous major collection.
|
||||
The default value is 100.
|
||||
|
||||
The major-minor multiplier controls the shift back to minor collections.
|
||||
For a multiplier @M{x},
|
||||
the collector will shift back to minor collections
|
||||
after a major collection collects at least @M{x%} of the allocated objects.
|
||||
In particular, for a multiplier of 0,
|
||||
the collector will immediately shift back to minor collections
|
||||
after doing one cycle of major collections.
|
||||
The default value is 20.
|
||||
|
||||
}
|
||||
|
||||
@ -3311,9 +3322,8 @@ Returns the remainder of dividing the current amount of bytes of
|
||||
memory in use by Lua by 1024.
|
||||
}
|
||||
|
||||
@item{@id{LUA_GCSTEP} @T{(int stepsize)}|
|
||||
Performs an incremental step of garbage collection,
|
||||
corresponding to the allocation of @id{stepsize} Kbytes.
|
||||
@item{@id{LUA_GCSTEP}|
|
||||
Performs a step of garbage collection.
|
||||
}
|
||||
|
||||
@item{@id{LUA_GCISRUNNING}|
|
||||
@ -3321,13 +3331,13 @@ Returns a boolean that tells whether the collector is running
|
||||
(i.e., not stopped).
|
||||
}
|
||||
|
||||
@item{@id{LUA_GCINC} (int pause, int stepmul, stepsize)|
|
||||
@item{@id{LUA_GCINC} (int pause, int stepmul, int stepsize)|
|
||||
Changes the collector to incremental mode
|
||||
with the given parameters @see{incmode}.
|
||||
Returns the previous mode (@id{LUA_GCGEN} or @id{LUA_GCINC}).
|
||||
}
|
||||
|
||||
@item{@id{LUA_GCGEN} (int minormul, int majormul)|
|
||||
@item{@id{LUA_GCGEN} (int minormul, int minormajor, int majorminor)|
|
||||
Changes the collector to generational mode
|
||||
with the given parameters @see{genmode}.
|
||||
Returns the previous mode (@id{LUA_GCGEN} or @id{LUA_GCINC}).
|
||||
@ -6312,13 +6322,14 @@ gives the exact number of bytes in use by Lua.
|
||||
|
||||
@item{@St{step}|
|
||||
Performs a garbage-collection step.
|
||||
The step @Q{size} is controlled by @id{arg}.
|
||||
With a zero value,
|
||||
the collector will perform one basic (indivisible) step.
|
||||
For non-zero values,
|
||||
the collector will perform as if that amount of memory
|
||||
(in Kbytes) had been allocated by Lua.
|
||||
Returns @true if the step finished a collection cycle.
|
||||
In incremental mode,
|
||||
that step corresponds to the current step size;
|
||||
the function returns @true if the step finished a collection cycle.
|
||||
In generational mode,
|
||||
the step performs a full minor collection or
|
||||
a major collection,
|
||||
if the collector has scheduled one;
|
||||
the function returns @true if the step performed a major collection.
|
||||
}
|
||||
|
||||
@item{@St{isrunning}|
|
||||
@ -6332,15 +6343,15 @@ This option can be followed by three numbers:
|
||||
the garbage-collector pause,
|
||||
the step multiplier,
|
||||
and the step size @see{incmode}.
|
||||
A zero means to not change that value.
|
||||
A -1 or absent value means to not change that value.
|
||||
}
|
||||
|
||||
@item{@St{generational}|
|
||||
Change the collector mode to generational.
|
||||
This option can be followed by two numbers:
|
||||
the garbage-collector minor multiplier
|
||||
and the major multiplier @see{genmode}.
|
||||
A zero means to not change that value.
|
||||
This option can be followed by three numbers:
|
||||
the garbage-collector minor multiplier,
|
||||
the minor-major multiplier, and the major-minor multiplier @see{genmode}.
|
||||
A -1 or absent value means to not change that value.
|
||||
}
|
||||
|
||||
}
|
||||
@ -9229,6 +9240,9 @@ declare a local variable with the same name in the loop body.
|
||||
@itemize{
|
||||
|
||||
@item{
|
||||
There were several changes in the parameters
|
||||
for the options @St{incremental} and @St{generational}
|
||||
of the function @Lid{collectgarbage}.
|
||||
}
|
||||
|
||||
}
|
||||
@ -9245,6 +9259,12 @@ it is equivalent to @Lid{lua_closethread} with
|
||||
@id{from} being @id{NULL}.
|
||||
}
|
||||
|
||||
@item{
|
||||
There were several changes in the parameters
|
||||
for the options @Lid{LUA_GCINC} and @Lid{LUA_GCGEN}
|
||||
of the function @Lid{lua_gc}.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user