天天看點

lua 垃圾回收機制

一、檢測lua記憶體洩漏:

lua 垃圾回收機制

注:使用“collectgarbage("collect")”,局部變量v被回收,my_list沒有被回收。

lua 垃圾回收機制

注:局部變量v占用的記憶體被回收。

lua 垃圾回收機制

注:将my_list置為nil,使用“collectgarbage("collect")”可以回收。

總結一: 如何監測Lua的程式設計産生記憶體洩露:

1.       針對會産生洩露的函數,先調用collectgarbage("count"),取得最初的記憶體使用

2.       函數調用後, collectgarbage("collect")進行收集, 并使用collectgarbage("count")再取得目前記憶體, 最後記錄兩次的使用差

3.       從test1的收集可看到, collectgarbage("collect")被調用,并不保證一次成功, 是以, 大可以調用多次

總結二: 如何避免Lua應用中出現的記憶體使用過大行為:

1.       當然是代碼實作不出現洩露

2.       在測試中,其實還發現, Lua中被配置設定的記憶體,其實并不會自動回收(個人估計要麼就是Lua虛拟機沒有做這個事情,要麼就是回收的時機是在C層), 是以, 為了避免記憶體過大, 應用的運作時,可能需要定期的(調用collectgarbage("collect"),又或者collectgarbage("step"))進行顯式回收。

 ----------------------------------------------------------------------------------

【使用LUA開發遊戲,發現記憶體耗費成倍增長】http://blog.sina.com.cn/s/blog_a17b071c0101itua.html

記憶體随着時間成倍增加,這個感覺應該是和堆棧配置設定有關系,但是看我們LUA架構代碼,大部分用到LUA地方都有進行釋放了呀。。。

挨個對照COCOS2D-X提供的LUA架構和我們的LUA架構,發現在一般的方法,比如執行字元串,執行檔案,等等ExecuteString,ExecuteScriptFile,ExecuteGlobalFunction函數寫法都一樣,于是範圍縮小到我們自己寫的幾個函數裡面。我們自己封裝的執行對話框内部函數ExecuteTableFunction,GetTableFuntion等幾個,仔細閱讀代碼後,終于發現問題了:

1)堆棧用完沒有及時恢複

2)沒有及時使用垃圾回收

 解決方案

1)在函數異常傳回或者正常處理傳回時,堆棧要進行恢複:

lua_pop(L, 1);

// 恢複之前的棧頂位置

lua_settop(L, 0);

2)在調用lua_pcall()時,要調用lua_gc(L, LUA_GCCOLLECT, 0);進行垃圾回收;

在這些修改後,重新進行編譯運作,這個時候再列印記憶體,發現就很OK了: