鍍金池/ 教程/ Java/ 垃圾回收機(jī)制
數(shù)據(jù)庫(kù)訪問(wèn)
循環(huán)
數(shù)組
錯(cuò)誤處理
面向?qū)ο?/span>
調(diào)試
游戲開發(fā)
文件 I/O
變量
迭代器
Web 編程
模塊
函數(shù)
元表
協(xié)程
垃圾回收機(jī)制
標(biāo)準(zhǔn)庫(kù)
決策
數(shù)據(jù)類型
運(yùn)行環(huán)境
操作符
字符串
基本語(yǔ)法
概述

垃圾回收機(jī)制

Lua 通過(guò)特定算法的垃圾回收機(jī)制實(shí)現(xiàn)自動(dòng)內(nèi)存管理。由于自動(dòng)內(nèi)存管理機(jī)制的存在,作為程序開發(fā)人員:

  • 不需要關(guān)心對(duì)象的內(nèi)存分配問(wèn)題。
  • 不再使用對(duì)象時(shí),除了將引用它的變量設(shè)為 nil,不需要主動(dòng)釋放對(duì)象。

Lua 的垃圾回收器會(huì)不斷運(yùn)行去收集不再被 Lua 程序訪問(wèn)的對(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í)間

該數(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ù)程序不同的特征,可以通過(guò)修改該值使得程序達(dá)到最佳的性能。

垃圾收集器步長(zhǎng)倍增器

步長(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)存分配的兩倍。

垃圾回收器相關(guān)函數(shù)

作為開發(fā)人員,我們可能需要控制 Lua 的自動(dòng)內(nèi)存管理機(jī)制,可以使用下面的這些方法:

  • collectgarbage("collect"):運(yùn)行一個(gè)完整的垃圾回收周期。
  • collectgarbage("count"):返回當(dāng)前程序使用的內(nèi)存總量,以 KB 為單位。
  • collectgarbage("restart"):如果垃圾回收器停止,則重新運(yùn)行它。
  • collectgarbage("setpause"):設(shè)置垃圾收集暫停時(shí)間變量的值,值由第二個(gè)參數(shù)指出(第二參數(shù)的值除以 100 后賦予變量)。稍后,我們將詳細(xì)討論它的用法。
  • collectgarbage("setsetmul"):設(shè)置垃圾收集器步長(zhǎng)倍增器的值,第二個(gè)參數(shù)的含義與上同。
  • collectgarbage("step"):進(jìn)行一次垃圾回收迭代。第二個(gè)參數(shù)值越大,一次迭代的時(shí)間越長(zhǎng);如果本次迭代是垃圾回收的最后一次迭代則此函數(shù)返回 true。
  • collectgarbage("stop"):停止垃圾收集器運(yùn)行。

下面的示例代碼中使用了垃圾收集器相關(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)存需求,我們可以使用到這些方法來(lái)提高程序的性能。雖然大部分情況下,我們都不會(huì)用到這些函數(shù),但是了解這些方法可以幫助我們調(diào)試程序,以免應(yīng)用上線后帶來(lái)的損失。

譯注:更多垃圾回收器的內(nèi)容請(qǐng)參考官網(wǎng)或者此博客

上一篇:錯(cuò)誤處理下一篇:概述