記憶體用量在 Android 遊戲開發中至關重要。 使用 Unreal Engine 開發遊戲時,您必須持續分析及追蹤記憶體狀態,以符合這些記憶體限制,避免記憶體流失和過度分配記憶體。
透過減少著色器排列組合節省記憶體
移除 Lighting 或 Mobile Shader Permutation
Reduction 中未使用的選項,即可盡量減少著色器排列組合的數量。這項功能可大幅縮減應用程式封裝大小、減少管道狀態物件 (PSO) 數量,並防止建立未使用的算繪目標或虛擬紋理,進而減少執行階段記憶體用量,提升效能。
詳情請參閱「行動裝置效能指南」中的「行動裝置的雜項照明和著色器排列組合縮減設定」一節。
素材資源載入最佳化
使用硬式參照載入資產時,即使遊戲中未使用連結的內容,也會同時載入至記憶體,造成不必要的記憶體消耗。特別是當藍圖中誤用繼承時,系統會從父項分配不必要的 CDO (類別預設物件),浪費大量記憶體。在這種情況下,請套用下列技巧來最佳化記憶體用量。
- C++ 程式碼定義和資料分隔:使用 C++ 程式碼中的
UCLASS(Abstract)定義核心功能,並將這些功能與實際資料分隔。 - 盡量減少繼承:只在葉節點藍圖中執行資料設定和資產載入作業。
- 使用間接參照:使用
TSoftObjectPtr套用間接屬性參照,避免硬式參照,並在執行階段嚴格按照需求非同步載入資產。 - 注意事項:使用非同步資產載入時,請務必在載入完成回呼期間執行有效性檢查 (
IsValid),以免指標懸空或發生當機。
詳情請參閱「參照資產」和「使用 UE5 建構行動遊戲」。
智慧指標和垃圾回收 (GC) 微調
在 C++ 開發期間使用智慧指標 (例如 TSharedPtr 和 TWeakPtr),可避免懸空指標和記憶體流失。此外,使用 TWeakPtr 可避免建立物件的強烈參照,因此垃圾收集器在收集物件時不會遞增參照計數。這可避免不必要的物件存留,並降低 GC 需要遍歷的參照圖複雜度,大幅減少 GC 負擔。在行動環境中,您可以觸發ForceGarbageCollection,在層級轉換或閒置期間 (例如沒有使用者互動時) 有效管理垃圾收集作業。此外,當遊戲處於可感知狀態或背景狀態 (例如 onStop 回呼) 時,系統也會觸發此事件,確保垃圾回收作業不會影響進行中的遊戲體驗。
使用重定位表壓縮進行最佳化
重定位表壓縮是一種最佳化方法,可壓縮 ELF 二進位檔中的重定位表大小,縮減 Android 二進位檔大小。當 Android minSDKVersion 為 23 以上時,系統支援 APS 重定位表壓縮;當 minSDKVersion 為 28 以上時,系統額外支援 RELR 重定位表壓縮,可大幅縮減 .so 檔案的大小。這不僅能縮減下載大小,還能減少執行階段 .so mmap 的記憶體用量,進而減輕整體實體記憶體壓力。
AndroidToolChain.cs
if (MinSDKVersion >= 28)
{
Result += " -Wl,--pack-dyn-relocs=android+relr,--use-android-relr-tags";
}
else if (MinSDKVersion >= 23)
{
Result += " -Wl,--pack-dyn-relocs=android";
}
如要套用這項最佳化措施,請確認已在「Project Settings」中啟用「Enable compression of relocation tables」,或已啟用 bEnableAdvancedBinaryCompression 變數。
如要檢查是否已正確將 RELR 壓縮套用至二進位檔,請使用 Android NDK 的 llvm-readelf 工具。
llvm-readelf -d libUnreal.so | grep RELR
實務上,建構 Unreal Engine 的 ThirdPerson 範本並使用 dumpsys meminfo 進行測量,可確認 .so mmap 的 PSS 和 RSS 使用量減少。
| 類別 | PSS 總用量 | Private Dirty | Private Clean | Swap Dirty | RSS 總用量 |
|---|---|---|---|---|---|
| .so mmap 壓縮前 | 170,210 | 24,360 | 141,564 | 0 | 242,204 |
| .so mmap 壓縮後 | 138,031 | 24,748 | 108,976 | 0 | 210,140 |
紋理壓縮
使用適當的材質壓縮功能,減少整體圖像資源的記憶體用量。使用Adaptive Scalable Texture Compression (ASTC) 行動標準,可提供比 ETC2 更優異的視覺品質,或是在相同的視覺品質目標下,以較低的記憶體用量達到更高的壓縮比。
紋理串流最佳化
在行動環境中,直接使用預設的 Unreal Engine 紋理串流集區大小,可能會預先分配相對於裝置規格過大的記憶體集區。因此,建議您定義行動裝置設定檔,並根據裝置記憶體限制選取適當的紋理串流集區大小。此外,您可以使用編輯器的「統計資料」功能,檢查紋理統計資料,並找出在執行階段佔用極高解析度的高記憶體消耗紋理。搭配必要紋理解析度功能,即可對耗用大量資源的紋理強制執行限制或降低解析度上限,將資源用量控制在分配的紋理記憶體緩衝區內。