Mengelola memori secara efektif dalam game

Pada platform Android, sistem mencoba menggunakan sebanyak mungkin memori sistem (RAM) dan melakukan berbagai pengoptimalan memori untuk mengosongkan ruang penyimpanan saat diperlukan. Pengoptimalan ini dapat berdampak negatif pada game Anda, dengan memperlambat atau menghentikannya sekaligus. Anda dapat mempelajari pengoptimalan ini lebih lanjut dalam topik Alokasi memori di antara proses.

Halaman ini menjelaskan langkah-langkah yang dapat Anda ambil untuk menghindari kondisi memori rendah yang memengaruhi game Anda.

Merespons onTrimMemory()

Sistem menggunakan onTrimMemory() untuk memberi tahu aplikasi Anda bahwa memori hampir habis dan aplikasi mungkin dihentikan. Sering kali, ini adalah satu-satunya peringatan yang diterima aplikasi Anda. Callback ini memiliki latensi tinggi terkait dengan low-memory killer (LMK), sehingga penting untuk merespons callback dengan cepat.

Dalam merespons callback ini, kurangi kecepatan, jumlah, dan ukuran alokasi. onTrimMemory() meneruskan konstanta yang menunjukkan keparahan, tetapi Anda harus merespons peringatan pertama karena dapat mengalokasikan lebih cepat daripada reaksi onTrimMemory().

Kotlin

class MainActivity : AppCompatActivity(), ComponentCallbacks2 {
    override fun onTrimMemory(level: Int) {
        when (level) {
            ComponentCallbacks2.TRIM_MEMORY_MODERATE,
                ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW,
                ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL -> // Respond to low memory condition
            else -> Unit
        }
    }
}

Java

public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 {
    public void onTrimMemory(int level) {
        switch (level) {
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
              // Respond to low memory condition
                break;
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
              // Respond to low memory condition
                break;
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
              // Respond to low memory condition
                break;
            default:
                break;

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())
    }
}

Menggunakan Memory Advice API dalam versi beta

Memory Advice API dikembangkan sebagai alternatif untuk onTrimMemory yang memiliki perolehan dan presisi yang jauh lebih tinggi dalam memprediksi LMK yang akan datang. API mencapai hal ini dengan memperkirakan jumlah resource memori yang digunakan, lalu memberi tahu aplikasi jika batas tertentu terlampaui. API juga dapat melaporkan perkiraan persentase penggunaan memori langsung ke aplikasi Anda. Anda dapat menggunakan Memory Advice API sebagai alternatif peristiwa onTrimMemory untuk tujuan pengelolaan memori.

Untuk menggunakan Memory Advice API, gunakan panduan memulai.

Bersikap konservatif dengan anggaran memori

Anggarkan memori secara konservatif untuk menghindari kehabisan memori. Beberapa item untuk dipertimbangkan adalah sebagai berikut:

  • Ukuran fisik RAM: Game sering menggunakan antara ¼ dan ½ jumlah fisik RAM pada perangkat.
  • Ukuran maksimum zRAM: Lebih banyak zRAM berarti game berpotensi memiliki lebih banyak memori untuk dialokasikan. Jumlah ini dapat bervariasi tergantung pada perangkat; cari SwapTotal di /proc/meminfo untuk menemukan nilai ini.
  • Penggunaan memori OS: Perangkat yang menentukan lebih banyak RAM ke proses sistem menyisakan lebih sedikit memori untuk game Anda. Sistem menghentikan proses game Anda sebelum menghentikan proses sistem.
  • Penggunaan memori aplikasi yang diinstal: Uji game Anda pada perangkat yang memiliki banyak aplikasi yang diinstal. Aplikasi media sosial dan chat harus berjalan secara konstan dan memengaruhi jumlah memori bebas yang tersedia.

Jika Anda tidak dapat menetapkan anggaran memori konservatif, lakukan pendekatan yang lebih fleksibel. Jika sistem mengalami masalah memori rendah, kurangi jumlah memori yang digunakan game. Misalnya, alokasikan tekstur resolusi lebih rendah atau simpan lebih sedikit shader sebagai respons terhadap onTrimMemory(). Pendekatan dinamis ke alokasi memori ini memerlukan lebih banyak pekerjaan dari developer, terutama dalam fase desain game.

Menghindari thrashing

Trashing terjadi saat memori kosong hampir habis, tetapi tidak cukup rendah untuk menghentikan game. Dalam situasi ini, kswapd telah mengklaim ulang halaman yang masih diperlukan game, sehingga mencoba memuat ulang halaman dari memori. Ruang penyimpanan tidak cukup, sehingga halaman terus tertukar (penukaran yang berkelanjutan). Pelacakan sistem melaporkan situasi ini sebagai thread tempat kswapd terus berjalan.

Salah satu gejala thrashing adalah waktu render frame yang panjang - kemungkinan satu detik atau lebih. Kurangi jejak memori game untuk mengatasi situasi ini.

Menggunakan fitur yang tersedia

Android memiliki sekumpulan alat untuk membantu memahami bagaimana sistem mengelola memori.

Meminfo

Alat ini mengumpulkan statistik memori untuk menunjukkan berapa banyak memori PSS yang dialokasikan dan kategori yang digunakannya.

Cetak statistik meminfo menggunakan salah satu dari cara berikut:

  • Gunakan perintah adb shell dumpsys meminfo package-name.
  • Gunakan panggilan MemoryInfo dari Debug API Android.

Statistik PrivateDirty menunjukkan jumlah RAM di dalam proses yang tidak dapat di-paging ke disk dan tidak dibagikan dengan proses lain. Sejumlah besar ini akan tersedia untuk sistem saat proses tersebut dihentikan.

Tracepoint memori

Tracepoint memori melacak jumlah memori RSS yang digunakan game Anda. Menghitung penggunaan memori RSS jauh lebih cepat daripada menghitung penggunaan PSS. Karena penghitungannya lebih cepat, RSS menunjukkan perincian yang lebih baik pada perubahan ukuran memori untuk pengukuran penggunaan memori puncak yang lebih akurat. Oleh karena itu, sebaiknya lihat puncak yang dapat menyebabkan game kehabisan memori.

Perfetto dan rekaman aktivitas yang panjang

Perfetto adalah rangkaian alat untuk mengumpulkan informasi performa dan memori di perangkat dan ditampilkan di UI berbasis web. Alat ini mendukung rekaman aktivitas panjang secara bebas sehingga Anda dapat melihat bagaimana RSS berubah seiring waktu. Anda juga dapat mengeluarkan kueri SQL mengenai data yang dihasilkan untuk pemrosesan offline. Mengaktifkan rekaman aktivitas panjang dari aplikasi Pelacakan Sistem. Pastikan kategori memory:Memory diaktifkan untuk rekaman aktivitas.

heapprofd

heapprofd adalah alat pelacakan memori yang merupakan bagian dari Perfetto. Alat ini dapat membantu Anda menemukan kebocoran memori dengan menunjukkan lokasi alokasi memori menggunakan malloc. heapprofd dapat dimulai menggunakan skrip Python, dan karena alat memiliki overhead yang rendah, hal ini tidak memengaruhi performa layaknya alat lain seperti Malloc Debug.

bugreport

bugreport adalah alat logging untuk mengetahui apakah game Anda mengalami error atau tidak karena kehabisan memori. Output alat ini jauh lebih detail daripada jika menggunakan logcat. Ini berguna untuk melakukan proses debug memori karena hal tersebut menunjukkan apakah game Anda mengalami error karena memori habis atau jika ditutup oleh LMK.

Untuk informasi selengkapnya, lihat Merekam dan membaca laporan bug.