Lua 通過特定算法的垃圾回收機(jī)制實(shí)現(xiàn)自動(dòng)內(nèi)存管理。由于自動(dòng)內(nèi)存管理機(jī)制的存在,作為程序開發(fā)人員:
Lua 的垃圾回收器會(huì)不斷運(yùn)行去收集不再被 Lua 程序訪問的對(duì)象。
所有的對(duì)象,包括表、userdata、函數(shù)、線程、字符串等都由自動(dòng)內(nèi)存管理機(jī)制管理它們空間的分配和釋放。Lua 實(shí)現(xiàn)了一個(gè)增量式標(biāo)記清除垃圾收集器。它用兩個(gè)數(shù)值控制垃圾回收周期,垃圾收集器暫停時(shí)間(garbage-collector pause) 和垃圾收集器步長(zhǎng)倍增器(garbage-collector step multiplier)。其數(shù)值是以百分制計(jì)數(shù)的,即數(shù)值 100 內(nèi)部表示 1。
該數(shù)值被用于控制垃圾收集器被 Lua 自動(dòng)內(nèi)存管理再次運(yùn)行之前需要的等待時(shí)長(zhǎng)。當(dāng)其小于 100 時(shí)意味著收集器在新周期開始前不再等待。其值越大垃圾回收器被運(yùn)行的頻率越低,越不主動(dòng)。當(dāng)其值 200 時(shí),收集器在總使用內(nèi)存數(shù)量達(dá)到上次垃圾收集時(shí)的兩倍時(shí)再開啟新的收集周期。因此,根據(jù)程序不同的特征,可以通過修改該值使得程序達(dá)到最佳的性能。
步長(zhǎng)倍增器用于控制了垃圾收集器相對(duì)內(nèi)存分配的速度。數(shù)值越大收集器工作越主動(dòng),但同時(shí)也增加了垃圾收集每次迭代步長(zhǎng)的大小。值小于 100 可能會(huì)導(dǎo)致垃圾器一個(gè)周期永遠(yuǎn)不能結(jié)束,建議不要這么設(shè)置。默認(rèn)值為 200,表示垃圾收集器運(yùn)行的速率是內(nèi)存分配的兩倍。
作為開發(fā)人員,我們可能需要控制 Lua 的自動(dòng)內(nèi)存管理機(jī)制,可以使用下面的這些方法:
下面的示例代碼中使用了垃圾收集器相關(guān)函數(shù),如下所示:
mytable = {"apple", "orange", "banana"}
print(collectgarbage("count"))
mytable = nil
print(collectgarbage("count"))
print(collectgarbage("collect"))
print(collectgarbage("count"))
運(yùn)行上面的程序,我們可以得到如下的輸出結(jié)果。請(qǐng)注意,輸出結(jié)果與操作系統(tǒng)類型與 Lua 自動(dòng)內(nèi)存管理都有關(guān),所以可能實(shí)際運(yùn)行的結(jié)果與下面不相同。
20.9560546875
20.9853515625
0
19.4111328125
從上面的程序,我們可以看出,一旦垃圾回收運(yùn)行后,使用的內(nèi)存量立即就減少了。但是,我們并不需要主動(dòng)去調(diào)用它。因?yàn)椋词刮覀儾徽{(diào)用此函數(shù),Lua 也會(huì)按配置的周期自動(dòng)的調(diào)用垃圾回收器。
顯然,如果需要,我們可以用上面的這些函數(shù)調(diào)整垃圾回收器的行為。這些函數(shù)幫且程序開發(fā)人員處理更加復(fù)雜的場(chǎng)景。根據(jù)開發(fā)的不同程序的內(nèi)存需求,我們可以使用到這些方法來提高程序的性能。雖然大部分情況下,我們都不會(huì)用到這些函數(shù),但是了解這些方法可以幫助我們調(diào)試程序,以免應(yīng)用上線后帶來的損失。
譯注:更多垃圾回收器的內(nèi)容請(qǐng)參考官網(wǎng)或者此博客。