Lua 提供了一個自動的內存管理。 這就是說你不須要關心建立新對象的分配內存操做,也不須要在這些對象再也不須要時的主動釋放內存。 Lua 經過運行一個垃圾收集器來自動管理內存,以此一遍又一遍的回收死掉的對象 (這是指 Lua 中再也不訪問的到的對象)佔用的內存。 Lua 中全部對象都被自動管理,包括: table, userdata、 函數、線程、和字符串。html
Lua 實現了一個增量標記清除的收集器。 它用兩個數字來控制垃圾收集週期: garbage-collector pause 和 garbage-collector step multiplier 。數據庫
garbage-collector pause 控制了收集器在開始一個新的收集週期以前要等待多久。 隨着數字的增大就致使收集器工做工做的不那麼主動。 小於 1 的值意味着收集器在新的週期開始時再也不等待。 當值爲 2 的時候意味着在總使用內存數量達到原來的兩倍時再開啓新的週期。網絡
step multiplier 控制了收集器相對內存分配的速度。 更大的數字將致使收集器工做的更主動的同時,也使每步收集的尺寸增長。 小於 1 的值會使收集器工做的很是慢,可能致使收集器永遠都結束不了當前週期。 缺省值爲 2 ,這意味着收集器將之內存分配器的兩倍速運行。函數
你能夠經過在 C 中調用 lua_gc
或是在 Lua 中調用 collectgarbage
來改變這些數字。 二者都接受百分比數值(所以傳入參數 100 意味着實際值 1 )。 經過這些函數,你也能夠直接控制收集器(例如,中止或是重啓)。lua
使用 C API , 你能夠給 userdata (參見 §2.8)設置一個垃圾收集的元方法。 這個元方法也被稱爲結束子。 結束子容許你用額外的資源管理器和 Lua 的內存管理器協同工做 (好比關閉文件、網絡鏈接、或是數據庫鏈接,也能夠說釋放你本身的內存)。spa
一個 userdata 可被回收,若它的 metatable 中有 __gc
這個域 , 垃圾收集器就不當即收回它。 取而代之的是,Lua 把它們放到一個列表中。 最收集結束後,Lua 針對列表中的每一個 userdata 執行了下面這個函數的等價操做:線程
function gc_event (udata) local h = metatable(udata).__gc if h then h(udata) end end
在每一個垃圾收集週期的結尾,每一個在當前週期被收集起來的 userdata 的結束子會以 它們構造時的逆序依次調用。 也就是說,收集列表中,最後一個在程序中被建立的 userdata 的 結束子會被第一個調用。code
weak table 是一個這樣的 table,它其中的元素都被弱引用。 弱引用將被垃圾收集器忽略掉, 換句話說, 若是對一個對象的引用只有弱引用, 垃圾收集器將回收這個對象。orm
weak table 的鍵和值均可以是 weak 的。 若是一個 table 只有鍵是 weak 的,那麼將運行收集器回收它們的鍵, 可是會阻止回收器回收對應的值。 而一個 table 的鍵和值都是 weak 時,就即容許收集器回收鍵又容許收回值。 任何狀況下,若是鍵和值中任一個被回收了,整個鍵值對就會從 table 中拿掉。 table 的 weak 特性能夠經過在它的 metatable 中設置 __mode
域來改變。 若是 __mode
域中是一個包含有字符 'k
' 的字符串時, table 的鍵就是 weak 的。 若是 __mode
域中是一個包含有字符 'v
' 的字符串時, table 的值就是 weak 的。htm
在你把一個 table 看成一個 metatable 使用以後, 就不能再修改 __mode
域的值。 不然,受這個 metatable 控制的 table 的 weak 行爲就成了未定義的。