網絡上在這一方面的介紹實在是太糟糕了(還是我理解無能,隨便吧。最近脾氣很不好謝謝)
如果一個數組,裏面有一個table對象,那麼即使將這個table賦值爲nil,它依然不會被垃圾回收因爲數組還存有着對這個對象的引用,顯然這樣的引用是沒有必要的。
爲了告訴GC,這一部分的引用是沒必要的,所以需要將其標記爲弱引用。以便GC可以對其進行回收
t1, t2 = {}, {}
arr = {}
arr[1] = t1
arr[2] = t2
t1 = nil --此時我們將t1賦值爲nil,表明這一部分的內容我們不需要再使用,可以被回收
collectgarbage() -- 手動執行gc回收操作
for k, v in pairs(arr) do
print(k, v)
end
結果如下所示
1 table: 0053B068
2 table: 0053B158
兩個表依然存在,並沒有被回收,因爲此時表arr還存在對他們的引用
我們使用 __mode 來標明弱引用關係
__mode 有兩個參數,“k"和"v” 他們也可以連起來一起使用"kv"
操作符 | 說明 |
---|---|
k | 表的key爲弱引用 |
v | 表的value爲弱引用 |
以上一個例子,可以重新寫成
t1, t2 = {}, {}
arr = {}
arr[1] = t1
arr[2] = t2
setmetatable(arr, {__mode = "v"})
t1 = nil --此時我們將t1賦值爲nil,表明這一部分的內容我們不需要再使用,可以被回收
collectgarbage() -- 手動執行gc回收操作
for k, v in pairs(arr) do
print(k, v)
end
結果爲
2 table: 007CB158
可以看到,這裏,第一個表被回收了。
以此類推,如果將表作爲鍵,那麼選擇"k"的模式,則會標記鍵爲弱引用。
而如果標記"kv",則只有當鍵和值同時爲弱引用的情況下才會被回收,而此例子的鍵是number類型,則會導致無論t1是否爲nil,都不會被回收,因爲類似bool、number等這些類型是不會被gc回收的