此頁面是關於為 Lua 5.1.4 製作緊急垃圾收集器補丁的說明。請注意 LuaFiveTwo 已將緊急垃圾收集器列為其中一項會納入的功能。針對此補丁所做的工作與 LuaFiveTwo 中可能納入的緊急垃圾收集器是分開進行的。緊急 GC 補丁讓您可以在記憶體配置失敗後安全呼叫 Lua 垃圾收集器。這允許垃圾收集器釋放一些記憶體,以便重試失敗的配置。此補丁還增加了設定 Lua 指令碼可配置多少記憶體的限制支援。
檔案
[下載 (5.1.4) 第 6 版緊急 GC 補丁]
[執行緊急垃圾收集的壓力測試程式。]
額外的記憶體最佳化功能。
這些包含在緊急 GC 補丁中。這些可以用於沒有緊急 GC 補丁的情況。
- 調整內部字串雜湊表的尺寸需要配置額外的雜湊表。對於需要在極小容量記憶體(64-256 KB)中執行的指令碼,這可能會導致在指令碼記憶體不足(只有 1-2 KB 可用)時產生「記憶體不足」的錯誤。我想到一個方法可以在沒有額外雜湊表的情況下調整雜湊表的尺寸。唯一的缺點是雜湊表中的一些字串會被移除並多次加入。因此,此方法會使用較多的 CPU 時間來節省額外的記憶體使用量。 [5.1.3 的字串表補丁]
- Lua 表格的雜湊區段也存在與字串雜湊表相同的調整尺寸問題。由於調整尺寸的程式碼較複雜,因此調整表格的雜湊區段的尺寸需要更多工序。 [5.1.3 的雜湊區段補丁]
有關 Lua 垃圾收集器運作原理的注意事項
免責聲明:這是我的第一個垃圾收集器開發專案,因此其中一些資訊可能會不正確。歡迎提供修正/修正建議。 --RobertGabrielJakabosky
「在開發此補丁的過程中,我必須了解 Lua 中的垃圾收集器如何運作。我寫下這些內容,以便在日後需要修正收集器的更多錯誤時幫助我,並且我希望這些資訊可以幫助其他對 Lua 垃圾收集器運作原理有興趣的人。」 --RobertGabrielJakabosky
簡要說明
Lua 垃圾收集器是一個標記和清除收集器。收集器有標記和清除這兩個主要階段,會在每個收集週期執行。在標記階段,收集器會遍歷 Lua 堆疊並進入表格中,將它找到的值標記為活資料。接著,清除階段會檢閱已收集值清單,並釋放它找到的所有死資料。
詳細說明
所有可收集類型物件具有「marked」位元欄位,其定義如下(摘自標頭檔「lgc.h」):
- 位 0 - 物件為白色(類型 0)
- 位 1 - 物件為白色(類型 1)
- 位 2 - 物件為黑色
- 位 3 - 用於使用者資料:已完成最後處理
- 位 3 - 用於表格:有弱鍵(請注意此位元具有兩個不同的意義,一個用於使用者資料,一個用於表格)
- 位 4 - 用於表格:有弱值
- 位 5 - 物件為固定(不應被收集)
- 位 6 - 物件為「超級」固定(僅主執行緒)
垃圾收集器會追蹤目前的白色(類型 0 或 1)以及具有另一白色且可以於掃描狀態收集的死物件。物件的顏色由設定的前 3 個位(0、1、2)決定。
- 如果設定兩個白色位元(0、1)中的任一位元,且黑色位元為清除狀態,則物件為白色。白色物件應只使用一個白色位元。
- 如果三個顏色位元(0、1、2)都為清除狀態,則物件為灰色。
- 如果設定黑色位元且兩個白色位元清除,則物件為黑色。
垃圾收集器狀態(每個收集週期依此順序通過這些狀態)
- GCSpause - 收集週期開始。在此狀態下,所有物件應標示為目前的白色。主要
lua_State
、全域變數表、註冊表和元表會標示為灰色並加入到灰色清單。狀態接著會變更為 GCSpropagate。 - GCSpropagate - 灰色清單中的每個物件會被移除並標示為黑色,接著任何它引用的白色(類型 0 或 1)物件會標示為灰色並加入到灰色清單。一旦灰色清單為空,目前的白色就會換成另個白色。標示為舊白色類型的所有物件現在都是死物件。狀態接著會變更為 GCSsweepstring。
- GCSsweepstring - 內部字串雜湊表的每個字串的顏色會被檢查。如果顏色與舊白色類型相符,該字串就會被視為死物件並予以釋放。如果顏色與目前的白色(新建立的字串)相符,或為灰色(另個物件引用它),則物件為存活,且其顏色會重設為目前的白色。一旦所有字串都檢查完畢,狀態會變更為 GCSsweep。
- GCSsweep - 全域 rootgc 清單(此清單會儲存除了字串外的所有物件)中每個物件的顏色會檢查,檢查方式與 GCSsweepstring 狀態下的字串相同。死物件會被釋放並從 rootgc 清單中移除。存活物件的顏色會重設為目前的白色。一旦所有物件都檢查完畢,狀態會變更為 GCSfinalize。
- GCSfinalize - 此狀態會執行
"__gc"
元方法讓所有死掉的使用者資料物件完成最後處理。一旦所有死掉的使用者資料物件都完成最後處理,狀態就會變更為 GCSpause,且此垃圾收集器週期完成。.
--RobertGabrielJakabosky
請參閱
近期變更 · 偏好設定
編輯 · 歷史記錄
上次編輯於 2010 年 12 月 8 日 上午 7:05 (GMT) (比較差異)