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。

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

最後附帶招聘貼

北京上市遊戲公司招聘客戶端程序員,手機MMO項目,做邏輯功能開發,或渲染、工具、底層框架。

要求編程和數據結構基礎紮實,聰明好學仔細認真,擅長團隊協作,溝通順暢對事不對人,有相關項目經驗或圖形學等特長尤佳。

公司待遇福利不錯,項目組有很多高手,公司也有技術積累,有意者站內信聯繫。


推薦閱讀:

這款遊戲耗盡了開發者的心血和眼淚,而你需要投入所有感情來玩
關於暴力摩托偽3D演算法?
開發者在購買遊戲引擎時到底購買了什麼?
還在忍受那些遊戲么?不如來做你自己的遊戲!(一)平台跳躍
比3A還要多1個A,這家120人的東歐小廠要挑戰育碧這樣的巨頭

TAG:游戏开发 | 性能优化 | Lua |