在 Android 平台上,系統會嘗試盡可能使用系統記憶體 (RAM),並視情況執行各種記憶體最佳化作業,以釋出空間。這些最佳化作業可能會對您的遊戲造成負面影響,不是使遊戲速度變慢,就是使遊戲完全終止。如要進一步瞭解這些最佳化作業,請參閱「程序之間的記憶體配置」這個主題。
本頁面說明可以採取哪些步驟,來避免記憶體不足導致遊戲受到影響的情況。
回應 onTrimMemory()
系統使用
onTrimMemory()
敬上
通知應用程式生命週期事件,
自行降低記憶體用量,避免
低記憶體終止工具 (LMK)
釋出記憶體供其他應用程式使用
如果應用程式在背景終止,則使用者下次啟動時。 就會導致 冷啟動。這類應用程式可減少 查看背景記憶體時 背景。
回應剪輯事件時,最好釋出大量記憶體配置
不需要立即重建,而且可以視需要重建。適用對象
例如,如果應用程式具有從本機解碼的點陣圖快取
嘗試修剪或清除這個檔案
快取
TRIM_MEMORY_UI_HIDDEN
。
Kotlin
class MainActivity : AppCompatActivity(), ComponentCallbacks2 { override fun onTrimMemory(level: Int) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } }
Java
public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 { public void onTrimMemory(int level) { switch (level) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } } }
C#
using UnityEngine; using System.Collections; using System.Collections.Generic; class LowMemoryTrigger : MonoBehaviour { private void Start() { Application.lowMemory += OnLowMemory; } private void OnLowMemory() { // Respond to low memory condition (e.g., Resources.UnloadUnusedAssets()) } }
使用 Memory Advice API Beta 版
Memory Advice API 是以
onTrimMemory 則比其他類型更高的喚回度和精確度
預測即將發生的 LMKAPI 會預估
應用程式會在某些情況下通知應用程式
超過門檻API 也能回報
記憶體用量Memory Advice API 可做為
onTrimMemory
敬上
以便管理記憶體
如要使用 Memory Advice API,請參閱入門指南。
對記憶體預算持保守態度
保守地分配記憶體預算,以免記憶體耗盡。以下列出一些需要注意的事項:
- 實體 RAM 大小:遊戲通常使用裝置上 ¼ 到 ½ 之間的實體 RAM 容量。
- zRAM 大小上限:如果 zRAM 容量較大,表示遊戲可能有更多記憶體可以分配。實際容量可能因裝置而異;在
/proc/meminfo
中尋找SwapTotal
,以找出這個值。 - OS 的記憶體用量:為系統程序指定較多 RAM 的裝置,留給遊戲較少記憶體。在終止系統程序前,系統會先終止遊戲程序。
- 安裝版應用程式的記憶體用量:在已安裝多個應用程式的裝置上測試遊戲。社群媒體和即時通訊應用程式必須持續執行,且會影響免費記憶體容量。
如果無法承諾以保守方式使用記憶體預算,請採取更為彈性的方法。如果系統碰到記憶體不足的問題,請減少遊戲使用的記憶體容量。例如,分配較低解析度的紋理或儲存較少著色器來回應 onTrimMemory()
。尤其在遊戲設計階段,這種動態分配記憶體配置的方式會增加開發人員的工作量。
避免輾轉現象
當免費記憶體偏低,但不至於導致遊戲終止時,就會發生「輾轉現象」。在這種情況下,kswapd
會收回遊戲所需的網頁,因此會嘗試從記憶體中重新載入網頁。空間不足,因此網頁會不斷替換 (連續替換)。
系統追蹤功能會將這個情形回報為 kswapd
持續執行的執行緒。
輾轉現象其中一個徵兆為影格時間較長,可能是一秒鐘或是更長。如要解決這個問題,請減少遊戲的記憶體用量。
使用可用的工具
Android 提供一系列工具,可協助您瞭解系統管理記憶體的方式。
Meminfo
這項工具會收集記憶體統計資料,以顯示 PSS 記憶體的分配情形,以及所使用的記憶體類別。
請以下列其中一種方式列印 meminfo 統計資料:
- 使用
adb shell dumpsys meminfo package-name
指令: - 使用 Android Debug API 的
MemoryInfo
呼叫。
PrivateDirty
統計資料會顯示程序中無法分頁至磁碟,且不會與任何其他程序共用的 RAM 容量。當相應的程序終止時,大部分的用量會開放給系統使用。
記憶體追蹤點
記憶體追蹤點會追蹤遊戲使用的 RSS 記憶體量。計算記憶體用量的速度比計算 PSS 用量來得快。RSS 可更快速地進行計算,因此能更精細地分析記憶體大小的變化,以更準確地測量尖峰記憶體用量。 因此,您會更容易注意到造成遊戲記憶體不足的尖峰用量。
Perfetto 與長期追蹤記錄
Perfetto 是一套工具,用於收集裝置上的效能和記憶體資訊,並將其顯示在網頁式的使用者介面中。這項工具支援任意長度的追蹤記錄,因此您可以查看 RSS 隨著時間的變化情形。 也可以針對這項工具產生的資料執行 SQL 查詢,以進行離線處理。請透過系統追蹤應用程式啟用長期追蹤記錄,並確認已啟用追蹤記錄的 memory:Memory 類別。
heapprofd
heapprofd
是 Perfetto 中的一種記憶體追蹤工具。這項工具使用 malloc
顯示記憶體分配位置,可協助發現記憶體流失的情況。heapprofd
可以使用 Python 指令碼啟動,而且由於這項工具造成的負擔較低,因此不像 Malloc Debug 等其他工具會影響效能。
bugreport
bugreport
是一款記錄工具,可協助您瞭解遊戲是否因記憶體不足而當機。相較於 Logcat,這項工具的輸出內容更為詳細。這對於記憶體偵錯很有幫助,因為這項工具會顯示遊戲是否因記憶體不足而當機,或是因 LMK 而終止。
詳情請參閱擷取和讀取錯誤報告一文。