diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-07-09 14:22:09 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-07-09 14:22:09 -0300 |
| commit | 626cf0581bc214722033d61c69d5db9e51e53465 (patch) | |
| tree | 53e219bda54f6985b33fb06a87dad68fb2a8f9ed | |
| parent | ccf6d098f6a46053ef671b42100e68f12352c5ec (diff) | |
| download | lua-626cf0581bc214722033d61c69d5db9e51e53465.tar.gz lua-626cf0581bc214722033d61c69d5db9e51e53465.tar.bz2 lua-626cf0581bc214722033d61c69d5db9e51e53465.zip | |
Generational mode may wait longer after a major collection
When Lua is building large long-duration structures, frequent small
minor collections just waste time. Trying to avoid this, the
collector will do a larger pause after a major collection when it
does not collect enough garbage (which is a hint that memory is
being used for long-lasting objects).
| -rw-r--r-- | lgc.c | 33 |
1 files changed, 25 insertions, 8 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.253 2018/03/16 14:22:09 roberto Exp roberto $ | 2 | ** $Id$ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <stdio.h> | 12 | #include <stdio.h> |
| 13 | #include <string.h> | 13 | #include <string.h> |
| 14 | 14 | ||
| 15 | |||
| 15 | #include "lua.h" | 16 | #include "lua.h" |
| 16 | 17 | ||
| 17 | #include "ldebug.h" | 18 | #include "ldebug.h" |
| @@ -1004,6 +1005,8 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | |||
| 1004 | ** ======================================================= | 1005 | ** ======================================================= |
| 1005 | */ | 1006 | */ |
| 1006 | 1007 | ||
| 1008 | static void setpause (global_State *g); | ||
| 1009 | |||
| 1007 | 1010 | ||
| 1008 | /* mask to erase all color bits, not changing gen-related stuff */ | 1011 | /* mask to erase all color bits, not changing gen-related stuff */ |
| 1009 | #define maskgencolors (~(bitmask(BLACKBIT) | WHITEBITS)) | 1012 | #define maskgencolors (~(bitmask(BLACKBIT) | WHITEBITS)) |
| @@ -1275,21 +1278,35 @@ static void fullgen (lua_State *L, global_State *g) { | |||
| 1275 | ** than last major collection (kept in 'g->GCestimate'), does a major | 1278 | ** than last major collection (kept in 'g->GCestimate'), does a major |
| 1276 | ** collection. Otherwise, does a minor collection and set debt to make | 1279 | ** collection. Otherwise, does a minor collection and set debt to make |
| 1277 | ** another collection when memory grows 'genminormul'% larger. | 1280 | ** another collection when memory grows 'genminormul'% larger. |
| 1281 | ** When it does a major collection, it then checks whether it could | ||
| 1282 | ** reclaim at least ?? memory. If not, it sets a long pause for the | ||
| 1283 | ** next collection. (Therefore, the next collection will be a major | ||
| 1284 | ** one, too.) | ||
| 1278 | ** 'GCdebt <= 0' means an explicit call to GC step with "size" zero; | 1285 | ** 'GCdebt <= 0' means an explicit call to GC step with "size" zero; |
| 1279 | ** in that case, always do a minor collection. | 1286 | ** in that case, always do a minor collection. |
| 1280 | */ | 1287 | */ |
| 1281 | static void genstep (lua_State *L, global_State *g) { | 1288 | static void genstep (lua_State *L, global_State *g) { |
| 1282 | lu_mem majorbase = g->GCestimate; | 1289 | lu_mem majorbase = g->GCestimate; /* memory after last major collection */ |
| 1283 | int majormul = getgcparam(g->genmajormul); | 1290 | lu_mem majorinc = (majorbase / 100) * getgcparam(g->genmajormul); |
| 1284 | if (g->GCdebt > 0 && | 1291 | lu_mem memnew = gettotalbytes(g); |
| 1285 | gettotalbytes(g) > (majorbase / 100) * (100 + majormul)) { | 1292 | if (g->GCdebt > 0 && memnew > majorbase + majorinc) { |
| 1286 | fullgen(L, g); | 1293 | fullgen(L, g); |
| 1294 | memnew = gettotalbytes(g); | ||
| 1295 | if (memnew < majorbase + (majorinc / 2)) { | ||
| 1296 | /* collected at least half of memory growth since last major | ||
| 1297 | collection; go back to minor collections */ | ||
| 1298 | luaE_setdebt(g, -(cast(l_mem, (memnew / 100)) * g->genminormul)); | ||
| 1299 | } | ||
| 1300 | else { | ||
| 1301 | /* memory seems to be growing; do a long wait for next (major) | ||
| 1302 | collection */ | ||
| 1303 | setpause(g); | ||
| 1304 | } | ||
| 1287 | } | 1305 | } |
| 1288 | else { | 1306 | else { |
| 1289 | lu_mem mem; | ||
| 1290 | youngcollection(L, g); | 1307 | youngcollection(L, g); |
| 1291 | mem = gettotalbytes(g); | 1308 | memnew = gettotalbytes(g); |
| 1292 | luaE_setdebt(g, -(cast(l_mem, (mem / 100)) * g->genminormul)); | 1309 | luaE_setdebt(g, -(cast(l_mem, (memnew / 100)) * g->genminormul)); |
| 1293 | g->GCestimate = majorbase; /* preserve base value */ | 1310 | g->GCestimate = majorbase; /* preserve base value */ |
| 1294 | } | 1311 | } |
| 1295 | } | 1312 | } |
