項目後期Lua接入筆記11--Lua代碼優化2

文章轉載自Unity3D遊戲優化之Lua的內存,感謝原作者燃野提供的好文章


近段時間處理了一些Lua相關的性能和內存問題,分享記錄下
1.lua內存增長很快,但gc可以降低的情況
一個小場景,角色站着不動內存就會穩定的增長,對比了unity profiler裏的數據,沒有特別顯著的變化,但是lua內存增長了很多
這裏寫圖片描述
執行lua gc後會大幅降低。說明是臨時對象佔用的內存,不gc釋放不掉。也確實沒開自動gc和定期gc,也算是爲了暴露問題。

接着用windows sdk裏的umdh(user mode dump heap)查出來是slua的pushVector3造成的
這裏寫圖片描述
緊接着反查都哪裏會調pushVector3,發現是lua和C#間進行Vector3類型轉換的時候會用到,後來發現是小地圖lua代碼裏每幀一次取UI組件的幾個position,頻率雖然不高,但引起的內存增長倒是不少。

項目開始的時候已經知道頻繁調用transform.position等會有性能問題,所以專門寫了不用進行vector3轉換的SetPostion(x, y, z)等方法,但沒有對position的相關方法做限制,口頭約定不要用position接口,但還會有人不注意。現在乾脆刪掉了transform裏position等相關的導出方法,用了就報錯,強制使用自定義的setter和getter。讓我再次想起來規範一定要做到工具裏,或者形成強制限制或檢查,不然就是沒用的規範。

這次比較幸運,是特殊的pushVector3造成的,如果之後是lua裏某些地方造成頻繁的創建臨時對象怕是都不好找到是哪塊lua代碼。

2.lua內存增長,但是gc不掉的情況

使用了雲風寫的lua snapshot,cloudwu/lua-snapshot
原理也是獲取兩個時間點的內存snapshot進行對比,找新申請未清除引用的,注意不是未釋放,釋放由gc來進行。

跟着服務器壓測時發現每處理一個player add消息會增加lua內存700k,且gc釋放不掉

在連續的2個palyer add消息的時候截取lua snapshot,對比發現大量內存被同一地址引用,有關鍵數字,搜一下60010發現是某數據表裏的數據,原來是重複緩存了數據表造成的。
這裏寫圖片描述

3.lua數據表內存優化

策劃添excel表,導成lua表爲客戶端和服務器所用,數據越來越多,佔了50M。

通過分析發現很多數據都是一樣的,分析需求建表的時候會刻意迴避動不動就添一列且只有少數行會用到這一列的情況,但實際上還出現了不少。m行xn列的數據,增長是很快的。

想到了用默認值的方式,每列出現次數最多的數據當作默認值,專門建一行默認值表。m行*n列的數據中如果跟默認值一樣,就不寫到表裏了,這樣可以隨意創建多列,即使利用率低也不會讓內存爆炸。用原表的__index就能實現有自定義值時取自定義的,沒有則取默認值的方式。

內存降低到33M,沒有預期中降低的多。

還有一種方法是去掉key,m行*n列中只按下標1..n存數據,原表裏存key到index的映射,適合一行中大多都不是默認值的情況,這個還沒實施測試。

默認值和去key的方式是可以混用的,根據每行數據的特點2選1。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章