Phần phức tạp nhất trong GC là đánh dấu (mark) đã được trình bày xong. Những phần còn lại khá đơn giản. Hôm nay sẽ hoàn thành toàn bộ nội dung.
Quy trình dọn dẹp (sweep) gồm hai giai đoạn: giai đoạn đầu xử lý các chuỗi ký tự, giai đoạn sau xử lý các đối tượng khác. Xem đoạn mã tại lgc.c dòng 573:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
case GCSsweepstring: {
lu_mem old = g->totalbytes;
sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
if (g->sweepstrgc >= g->strt.size) /* không còn gì để dọn nữa? */
g->gcstate = GCSsweep; /* kết thúc giai đoạn quét chuỗi */
lua_assert(old >= g->totalbytes);
g->estimate -= old - g->totalbytes;
return GCSWEEPCOST;
}
case GCSsweep: {
lu_mem old = g->totalbytes;
g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
if (*g->sweepgc == NULL) { /* không còn gì để quét nữa? */
checkSizes(L);
g->gcstate = GCSfinalize; /* kết thúc giai đoạn quét */
}
lua_assert(old >= g->totalbytes);
g->estimate -= old - g->totalbytes;
return GCSWEEPMAX*GCSWEEPCOST;
}
|
Trong trạng thái GCSsweepstring, mỗi bước gọi sweepwholelist
sẽ xử lý một cột trong bảng băm của strt
. Trong điều kiện lý tưởng, mọi chuỗi đều được phân bố đều trong bảng băm không có va chạm, mỗi cột sẽ chứa đúng một chuỗi. Chúng ta có thể tham khảo đoạn mã tại lstring.c dòng 68: