一、檢測lua內存泄漏:
注:使用“collectgarbage("collect")”,局部變量v被回收,my_list沒有被回收。
注:局部變量v占用的內存被回收。
注:將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了:
---------------------------------------------------------------------------------------------