Lua模塊的加載與內存釋放

今天早上據說一件事情讓我以爲很詭異的事情:公司線上的一款遊戲,加載一份配置資源後,內存漲了幾十M,而後內存再也下不來了。由於好奇,因此要來了最大的一個配置文件(4.5M,去除空格與換行後的大小),進行測試。最終發現,內存實際上是能夠被釋放的,不過須要注意如下的規則。html

 

同時,爲了證實luac 與 luajit 表現一致,我同時也使用了 luajit 進行了測試。json

前往下載頁面 http://luajit.org/download.html  ,而後下載最新版本 函數

image

在開始菜單中找到 Visual Studio的 Command Prompts測試

image

進入下載好的 luajit 解壓目錄 LuaJIT-2.1.0-beta2/src  運行 msvcbuild.batui

 

重點在模塊的編寫,模塊編寫的方法致使了釋放內存的不一樣。lua

 

當 require 準備加載一個 lua 文件時,它會先檢測 package.loaded[modulename] 是否返回 false,若是不是 false,它直接返回相應存儲的值,不然查找並加載相應的文件,找不到就報錯。spa

 

當加載的一個 lua 模塊,若是沒有 return 任何值時,package.loaded[modulename] 值爲 true。3d

當加載一個 lua 模塊,返回一個 table 時,package.loaded[modulename] 值爲 table。code

 

我拿到的 lua 文件是這樣定義的,本來是一個json,將其轉爲lua的,將全部數據賦值給一個變量(require 以後多了一個全局變量),這樣 package.loaded[modulename] 爲 true,重置這個值並不會回收內存,須要同時清理全局變量(將相應變量置爲 nil),才能夠實現內存的回收。htm

 

示例代碼:

local a = require(「b」)

-- clear

a = nil

package.loaded[「b」] = nil

 

collectgarbage()
print(collectgarbage("count") / 1024)

 

能夠針對上面的函數,封裝一個unrequire

function unrequire(m)
    package.loaded[m] = nil
    _G[m] = nil
end

 

實際測試的示例

內存回收

上面的20.xx是M,你沒看錯。一個約4.5M的 lua 文件,被 require 進內存後,lua 所佔用的內存大小變爲 20M。爲何會這麼大,有待進一步從源碼中尋找答案。

相關文章
相關標籤/搜索