iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

0
Software Development

30天 Lua重拾筆記系列 第 31

【30天Lua重拾筆記31】進階議題: 記憶體回收&弱表

TL;DR:
不要去修改預設值,除非你知道在做什麼

Lua會自己做記憶體回收,絕大多數時候不必為記憶體分配、管理而操心,而且通常它做的很好。但如果真的因為記憶體回收而影響到程式效率的執行,且你確定你有足夠的記憶體,你可以暫停讓Lua執行記憶體回收的操作:

停止收集記憶體垃圾

collectgarbage("stop")
collectgarbage("isrunning") --> false

或者,如果你是嵌入在C,可能會更傾向使用:

lua_gc(L, LUA_GCSTOP)

收集記憶體垃圾

如果要恢復,也只要:

collectgarbage("restart")
collectgarbage("isrunning") --> true

或是

lua_gc(L, LUA_GCRESTART)

記憶體收集策略

如果你很了解不同種的記憶體收集策略的優劣,Lua提供以下記憶體收集策略:

  • "collect"
    預設模式
  • "stop"
    除了手動觸發以外,不執行記憶體回收。
  • "step"
  • "incremental"
  • "generational"

弱表

metatable有一個選項是__mode,可以使表變成是弱表,他有三個值 -- "k""v""kv"k就是key,也就是如果表的索引值是可以被回收,而且被回收了,這個欄位也就被回收了。v對應的是value,也就是如果表的值是可以被回收,而且被回收了,這個欄位也就被回收了。kv只要索引值或值其一被回收了,就不在保留該欄位。我們直接拿kv來試試:

collectgarbage("restart") -- 開始自動記憶體回收

weak_table = {}
setmetatable(weak_table, {__mode = "kv"})

key = {}
value = {}

weak_table[key] = 1
weak_table[10] = value

for k, v in pairs(weak_table) do
  print(k, v)  -- {[key] = 1, [10] = value}
end

key = nil
value = nil    -- 不保留(刪除) key, value

collectgarbage()  -- 執行記憶體回收

for k, v in pairs(weak_table) do
  print(k, v)  -- nothing
end

意外嗎?旅途還在繼續,在聽我囉唆幾天XD。
本文同步發表於個人網站


上一篇
【30天Lua重拾筆記30】進階議題: 與C交互(+Python)
下一篇
【30天Lua重拾筆記32】進階議題: LuaRocks & LuaDist
系列文
30天 Lua重拾筆記36

尚未有邦友留言

立即登入留言