Oyunlarda hafızayı etkili şekilde yönetin

Android platformunda sistem, mümkün olduğunca fazla sistem belleği (RAM) kullanmaya çalışır ve gerektiğinde yer açmak için çeşitli bellek optimizasyonları gerçekleştirir. Bu optimizasyonlar, oyununuzu yavaşlatarak veya tamamen kapatarak olumsuz etkileyebilir. Bu optimizasyonlar hakkında daha fazla bilgiyi İşlemler arasında bellek ayırma başlıklı makalede bulabilirsiniz.

Cihaz kararlılığını sağlamak için Android 17'den (API düzeyi 37) itibaren sistem, cihazın toplam RAM'ine göre uygulama bellek sınırlarını zorunlu kılmaya başlar. Bir uygulama bu sınırları aşarsa Android, işlemle ilişkili yığın izi olmadan işlemi sonlandırır.

Bu sayfada, oyununuzu etkileyen düşük bellek koşullarından kaçınmak için uygulayabileceğiniz adımlar açıklanmaktadır.

onTrimMemory() işlevine yanıt verme

Sistem, uygulamanızı, uygulamanızın bellek kullanımını gönüllü olarak azaltması ve diğer uygulamaların kullanması için bellek boşaltmak üzere düşük bellek nedeniyle işlem sonlandırma (LMK) tarafından sonlandırılmaktan kaçınması için iyi bir fırsat sunan yaşam döngüsü etkinlikleri hakkında bilgilendirmek üzere onTrimMemory() kullanır.

Uygulamanız arka planda sonlandırılırsa kullanıcı, uygulamanızı bir sonraki başlatışında yavaş bir sıfırdan başlatma deneyimi yaşar. Arka plana geçerken bellek kullanımını azaltan uygulamaların arka planda sonlandırılma olasılığı daha düşüktür.

Kırpma etkinliklerine yanıt verirken, hemen ihtiyaç duyulmayan ve isteğe bağlı olarak yeniden oluşturulabilecek büyük bellek ayırmalarını serbest bırakmak en iyisidir. Örneğin, uygulamanızda yerel olarak depolanan sıkıştırılmış resimlerden çözülen bit eşlemlerin önbelleği varsa TRIM_MEMORY_UI_HIDDEN yanıt olarak bu önbelleği kırpmak veya temizlemek genellikle iyi bir fikirdir.

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.
            }
        }
    }
}

Bellek bütçeleri konusunda tutumlu olun

Belleğin tükenmesini önlemek için bellek bütçesini tutumlu bir şekilde kullanın. Göz önünde bulundurulması gereken bazı noktalar şunlardır:

  • Fiziksel RAM boyutu: Oyunlar genellikle cihazdaki fiziksel RAM miktarının ¼'ü ile ½'si arasında bir bölümünü kullanır.
  • Maksimum zRAM boyutu: Daha fazla zRAM, oyunun tahsis edebileceği daha fazla bellek olduğu anlamına gelir. Bu miktar cihaza göre değişebilir. Bu değeri bulmak için /proc/meminfo bölümünde SwapTotal simgesini arayın.
  • İşletim sisteminin bellek kullanımı: Sisteme daha fazla RAM ayıran cihazlarda oyununuz için daha az bellek kalır. Sistem, sistem işlemlerini sonlandırmadan önce oyununuzun işlemini sonlandırır.
  • Yüklü uygulamaların bellek kullanımı: Oyununuzu, çok sayıda uygulamanın yüklü olduğu cihazlarda test edin. Sosyal medya ve sohbet uygulamalarının sürekli çalışması gerekir ve bu durum, boş bellek miktarını etkiler.

Muhafazakar bir bellek bütçesi ayırmayı kabul edemiyorsanız daha esnek bir yaklaşım benimseyin. Sistem düşük bellek sorunlarıyla karşılaşırsa oyunun kullandığı bellek miktarını azaltın. Örneğin, onTrimMemory() yanıtı olarak daha düşük çözünürlüklü dokular ayırın veya daha az gölgelendirici depolayın. Bellek ayırmaya yönelik bu dinamik yaklaşım, özellikle oyun tasarımı aşamasında geliştiricinin daha fazla çalışmasını gerektirir.

Aşırı bellek kullanımını önleme

Thrashing, boş bellek azaldığında ancak oyunu sonlandıracak kadar azalmadığında meydana gelir. Bu durumda, kswapd, oyunun hâlâ ihtiyaç duyduğu sayfaları geri almış olduğundan sayfaları bellekten yeniden yüklemeye çalışır. Yeterli alan olmadığından sayfalar sürekli olarak değiştiriliyor (sürekli değiştirme). Sistem izleme, bu durumu kswapd'nin sürekli olarak çalıştığı bir iş parçacığı olarak bildirir.

Aşırı bellek kullanımının bir belirtisi, uzun kare süreleridir (bir saniye veya daha uzun olabilir). Bu durumu çözmek için oyunun bellekte kapladığı yeri azaltın.

Mevcut araçları kullanma

Android, sistemin belleği nasıl yönettiğini anlamanıza yardımcı olacak bir dizi araç sunar.

Meminfo

Bu araç, ne kadar PSS belleğinin ayrıldığını ve hangi kategorilerde kullanıldığını göstermek için bellek istatistiklerini toplar.

meminfo istatistiklerini aşağıdaki yöntemlerden birini kullanarak yazdırın:

  • adb shell dumpsys meminfo package-name komutunu kullanın.
  • Android Debug API'den MemoryInfo çağrısını kullanın.

PrivateDirty istatistiği, işlem içinde diske aktarılamayan ve diğer işlemlerle paylaşılmayan RAM miktarını gösterir. Bu miktarın büyük bir kısmı, işlem sonlandırıldığında sistem tarafından kullanılabilir.

Bellek izleme noktaları

Bellek izleme noktaları, oyununuzun kullandığı RSS belleği miktarını izler. RSS bellek kullanımını hesaplamak, PSS kullanımını hesaplamaktan çok daha hızlıdır. Hesaplanması daha hızlı olduğu için RSS, bellek boyutu değişikliklerinde daha ayrıntılı bir ayrıntı düzeyi göstererek en yüksek bellek kullanımının daha doğru ölçülmesini sağlar. Bu nedenle, oyunun belleğinin tükenmesine neden olabilecek zirveleri fark etmek daha kolaydır.

Perfetto ve uzun izler

Perfetto, bir cihazdaki performans ve bellek bilgilerini toplayıp web tabanlı bir kullanıcı arayüzünde görüntülemek için kullanılan bir araç paketidir. RSS'nin zaman içinde nasıl değiştiğini görebilmeniz için rastgele uzunluktaki izlemeleri destekler. Ayrıca, çevrimdışı işleme için oluşturduğu veriler üzerinde SQL sorguları da yayınlayabilirsiniz. Sistem İzleme uygulamasından uzun izlemeleri etkinleştirin. İzleme için memory:Memory kategorisinin etkinleştirildiğinden emin olun. Geliştirme ve test aşamasındaki özel bellek enstrümantasyonu için (Beta)heapprofd API'yi de kullanabilirsiniz.

heapprofd

heapprofd, Perfetto'nun bir parçası olan bir bellek izleme aracıdır. Bu araç, malloc kullanılarak belleğin nerede ayrıldığını göstererek bellek sızıntılarını bulmanıza yardımcı olabilir. heapprofd, bir Python komut dosyası kullanılarak başlatılabilir ve araç düşük ek yüke sahip olduğundan Malloc Debug gibi diğer araçlar gibi performansı etkilemez.

hata raporu

bugreport, oyununuzun bellek yetersizliğinden dolayı kilitlenip kilitlenmediğini öğrenmenizi sağlayan bir günlük kaydı aracıdır. Bu aracın çıktısı, logcat kullanmaktan çok daha ayrıntılıdır. Oyununuzun bellek yetersizliğinden dolayı kilitlenip kilitlenmediğini veya LMK tarafından sonlandırılıp sonlandırılmadığını gösterdiği için bellek hata ayıklama açısından faydalıdır.

Daha fazla bilgi için Hata raporlarını yakalama ve okuma başlıklı makaleyi inceleyin.