Lua 采用了自動(dòng)內(nèi)存管理。 這意味著你不用操心新創(chuàng)建的對(duì)象需要的內(nèi)存如何分配出來(lái), 也不用考慮在對(duì)象不再被使用后怎樣釋放它們所占用的內(nèi)存。
Lua 運(yùn)行了一個(gè)垃圾收集器來(lái)收集所有死對(duì)象 (即在 Lua 中不可能再訪(fǎng)問(wèn)到的對(duì)象)來(lái)完成自動(dòng)內(nèi)存管理的工作。 Lua 中所有用到的內(nèi)存,如:字符串、表、用戶(hù)數(shù)據(jù)、函數(shù)、線(xiàn)程、 內(nèi)部結(jié)構(gòu)等,都服從自動(dòng)管理。
Lua 實(shí)現(xiàn)了一個(gè)增量標(biāo)記-掃描收集器。 它使用這兩個(gè)數(shù)字來(lái)控制垃圾收集循環(huán): 垃圾收集器間歇率和垃圾收集器步進(jìn)倍率。 這兩個(gè)數(shù)字都使用百分?jǐn)?shù)為單位 (例如:值 100 在內(nèi)部表示 1 )。
垃圾收集器間歇率控制著收集器需要在開(kāi)啟新的循環(huán)前要等待多久。 增大這個(gè)值會(huì)減少收集器的積極性。 當(dāng)這個(gè)值比 100 小的時(shí)候,收集器在開(kāi)啟新的循環(huán)前不會(huì)有等待。 設(shè)置這個(gè)值為 200 就會(huì)讓收集器等到總內(nèi)存使用量達(dá)到 之前的兩倍時(shí)才開(kāi)始新的循環(huán)。
垃圾收集器步進(jìn)倍率控制著收集器運(yùn)作速度相對(duì)于內(nèi)存分配速度的倍率。 增大這個(gè)值不僅會(huì)讓收集器更加積極,還會(huì)增加每個(gè)增量步驟的長(zhǎng)度。 不要把這個(gè)值設(shè)得小于 100 , 那樣的話(huà)收集器就工作的太慢了以至于永遠(yuǎn)都干不完一個(gè)循環(huán)。 默認(rèn)值是 200 ,這表示收集器以?xún)?nèi)存分配的"兩倍"速工作。
如果你把步進(jìn)倍率設(shè)為一個(gè)非常大的數(shù)字 (比你的程序可能用到的字節(jié)數(shù)還大 10% ), 收集器的行為就像一個(gè) stop-the-world 收集器。 接著你若把間歇率設(shè)為 200 , 收集器的行為就和過(guò)去的 Lua 版本一樣了: 每次 Lua 使用的內(nèi)存翻倍時(shí),就做一次完整的收集。
Lua 提供了以下函數(shù)collectgarbage ([opt [, arg]])用來(lái)控制自動(dòng)內(nèi)存管理:
collectgarbage("collect"): 做一次完整的垃圾收集循環(huán)。通過(guò)參數(shù) opt 它提供了一組不同的功能:
collectgarbage("count"): 以 K 字節(jié)數(shù)為單位返回 Lua 使用的總內(nèi)存數(shù)。 這個(gè)值有小數(shù)部分,所以只需要乘上 1024 就能得到 Lua 使用的準(zhǔn)確字節(jié)數(shù)(除非溢出)。
collectgarbage("restart"): 重啟垃圾收集器的自動(dòng)運(yùn)行。
collectgarbage("setpause"): 將 arg 設(shè)為收集器的 間歇率 (參見(jiàn) §2.5)。 返回 間歇率 的前一個(gè)值。
collectgarbage("setstepmul"): 返回 步進(jìn)倍率 的前一個(gè)值。
collectgarbage("step"): 單步運(yùn)行垃圾收集器。 步長(zhǎng)"大小"由 arg 控制。 傳入 0 時(shí),收集器步進(jìn)(不可分割的)一步。 傳入非 0 值, 收集器收集相當(dāng)于 Lua 分配這些多(K 字節(jié))內(nèi)存的工作。 如果收集器結(jié)束一個(gè)循環(huán)將返回 true 。
collectgarbage("stop"): 停止垃圾收集器的運(yùn)行。 在調(diào)用重啟前,收集器只會(huì)因顯式的調(diào)用運(yùn)行。
以下演示了一個(gè)簡(jiǎn)單的垃圾回收實(shí)例:
mytable = {"apple", "orange", "banana"} print(collectgarbage("count")) mytable = nil print(collectgarbage("count")) print(collectgarbage("collect")) print(collectgarbage("count"))
執(zhí)行以上程序,輸出結(jié)果如下(注意內(nèi)存使用的變化):
20.9560546875 20.9853515625 0 19.4111328125
更多建議: