lua4 垃圾收集 collectgarbage


1.垃圾收集

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


2.垃圾收集的元方法

使用 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


3,Weak Table(弱表)

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 行爲就成了未定義的。

相關文章
相關標籤/搜索