《天諭》手游的記憶體控制 -筆記

花了100塊買了UWA上的這個課程,做個一個筆記

Profiler工具

推薦使用XCode分析記憶體,更準確

一、記憶體指標的類型:

VSS:Virtual Set Size,虛擬耗用記憶體。它是一個進程能訪問的所有記憶體空間地址的大小。這個大小包含了 一些沒有駐留在RAM中的記憶體,就像mallocs已經被分配,但還沒有寫入。VSS很少用來測量程式的實際使 用記憶體。

RSS:Resident Set Size,實際使用物理記憶體。RSS是一個進程在RAM中實際持有的記憶體大小。RSS可能會 產生誤導,因為它包含了所有該進程使用的共享庫所佔用的記憶體,一個被載入到記憶體中的共享庫可能有很 多進程會使用它。RSS不是單個進程使用記憶體量的精確表示。

PSS:Proportional Set Size,實際使用的物理記憶體,它與RSS不同,它會按比例分配共享庫所佔用的記憶體。 例如,如果有三個進程共享一個佔30頁記憶體控制項的共享庫,每個進程在計算PSS的時候,只會計算10頁。 PSS是一個非常有用的數值,如果系統中所有的進程的PSS相加,所得和即為系統佔用記憶體的總和。當一個 進程被殺死後,它所佔用的共享庫記憶體將會被其他仍然使用該共享庫的進程所分擔。在這種方式下,PSS 也會帶來誤導,因為當一個進程被殺後,PSS並不代表系統回收的記憶體大小。

USS:Unique Set Size,進程獨自佔用的物理記憶體。這部分記憶體完全是該進程獨享的。USS是一個非常有用 的數值,因為它表明了運行一個特定進程所需的真正記憶體成本。當一個進程被殺死,USS就是所有系統回 收的記憶體。USS是用來檢查進程中是否有記憶體泄露的最好選擇。

簡單來說,主要我們檢測PSS,USS。

USS = 進程獨佔的記憶體
RSS = USS + 共享記憶體
PSS = USS + 共享記憶體/共享這段記憶體的進程數量

如何獲取PSS、USS

在unity中:

Debug.MemoryInfo localMemoryInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(localMemoryInfo);
localMemoryInfo.getTotalPss();
localMemoryInfo.getTotalPrivateDirty();//USS

使用adb:

adb shell dumpsys meminfo 進程名
(結果里privte dirty就是USS)

二、資源記憶體優化

貼圖優化

主要還是講的那些老生常談的Tips。

  1. 格式ASTC8 x 8,部分精度要求高的6 x 6 或者 4 x 4

    Ios放棄iPhone5s/iPad mini3

    Android給低配機單獨的包(ETC 8 bits)

  2. 【尺寸】控制貼圖尺寸

  3. 【尺寸】針對不同貼圖單獨縮放尺寸

  4. 【Mipmaps】UI等貼圖關閉Mipmaps,不然會多33%的記憶體

  5. 【Read/Write】關閉貼圖的Read/Write Enabled,否則CPU和GPU都會有一份

  6. 【張數】去掉重複的貼圖,合併通道減少貼圖張數

《天諭》手游貼圖規範:

Mesh記憶體優化Tips
  1. 控制網格定點和三角形數量
  2. Mesh Lod可以有效降低面數和記憶體
  3. 去掉不用的定點屬性(uv, colors等等)
  4. 建議關閉網格的Read/Write

《天諭》手游的Mesh規範:

動畫
  1. MMO幀率30基本夠
  2. 嚴格控制動畫時長
  3. Generic可以通過壓縮浮點精度/去除scale曲線/keyframe reduction等方式進行壓縮
  4. Humanoid動畫比generic動畫要小
  5. 壓縮(Optimal 默認 2 2 2)
  6. 儘可能的復用動畫資源(Retarget)
  7. Animator Controller會載入所有動畫,需要優化
其他
  1. 中文字體裁剪(FontCreator + FontSubsetPack) 12M → 3M
  2. RenderTexture張數 尺寸 格式
  3. AssetBundle去掉TypeTree!可以減少30%-50%左右的記憶體,還可以略微提高載入解析速度
  4. 音頻優化(通道/碼率/streaming/按需載入)

三、腳本記憶體優化

  1. 控制高頻的記憶體分配
  2. 控制大塊的記憶體申請
  3. 控制容易導致gc alloc的函數調用
  4. 快取和復用

《天諭》項目組的程式碼規範

程式碼C++化

why

  1. 提高運算性能
  2. 減少頻繁調用導致的頻繁GC

What

  1. XML文件解析
  2. 網路包處理
  3. 屬性和戰鬥結算
  4. 數據表壓縮

風險

  1. 無法熱更
Shader記憶體優化

Shader這塊沒什麼好說的,控制了一些變體之後,他們的總記憶體從130MB降到了41MB。

最後使用IPreprocessShaders將記憶體又降到了10Mb左右

四、總量控制、分級管理

由於《天諭》的資源太大,如果不做總量控制,直接載入進來的話,隨時可能會撐爆記憶體。所以他們做了一套預算管理系統。控制著每個資源的創建,與自動降級。

對不同機型的配置,他們做了一個專門的設置介面,主要針對各種ios設備,設置各種高中低的開關

前期的資源,性能規範雖然很難做,但還是要去做。

這是他們的資源分析系統,可以看到有多個任務在執行。

最後的總結: