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 tentang peristiwa siklus proses yang memberikan peluang baik bagi aplikasi untuk mengurangi penggunaan memorinya secara sukarela dan menghindari penghentian penggunaan low-memory killer (LMK) untuk melepaskan memori agar bisa digunakan oleh aplikasi lain.

Jika aplikasi Anda dihentikan di latar belakang, saat berikutnya pengguna meluncurkan aplikasi Anda, mereka akan mengalami cold start. Aplikasi yang mengurangi penggunaan memori saat beralih ke latar belakang cenderung tidak dihentikan di latar belakang.

Saat merespons peristiwa pemangkasan, sebaiknya lepaskan alokasi memori besar yang tidak segera diperlukan dan dapat direkonstruksi sesuai permintaan. Sebagai misalnya, jika aplikasi Anda memiliki cache bitmap yang didekode dari gambar terkompresi yang tersimpan, sebaiknya memangkas atau menghapusnya secara permanen cache sebagai respons terhadap 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())
    }
}

Menggunakan Memory Advice API dalam versi beta

Memory Advice API dikembangkan sebagai alternatif untuk onTrimMemory yang memiliki perolehan dan presisi yang jauh lebih tinggi memprediksi LMK yang akan datang. API mencapai hal ini dengan memperkirakan jumlah sumber daya memori yang sedang digunakan, dan kemudian memberi tahu aplikasi ketika batas terlampaui. API juga dapat melaporkan estimasi persentase penggunaan memori langsung ke aplikasi Anda. Anda dapat menggunakan Memory Advice API sebagai alternatif untuk onTrimMemory {i>event<i} untuk tujuan manajemen 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.