Bellek yönetimi hakkında

Bellek optimizasyonu, Android'de kararlı ve yüksek performanslı oyun deneyimleri sunmak için kritik öneme sahiptir. Bu rehberde, bellek verimliliğinin neden önemli olduğu, Android işletim sisteminin işlem belleği sınırlarını nasıl yönetip uyguladığı ve Google Play Console'da oyununuzun teknik kalitesini izlemenize ve iyileştirmenize yardımcı olmak için kullanıma sunulan yeni eşikler hakkında genel bilgiler verilmektedir.

Bellek optimizasyonunun önemi

Oyuncuları elde tutma oranını korumak, cihaz uyumluluğunu artırmak ve platform kalite standartlarına uymak için oyununuzun belleğini optimize etmeniz gerekir:

  • Baştan başlatmayı önleme (kullanıcı deneyimi ve elde tutma): Bir oyuncu oyununuzdan geçici olarak ayrıldığında (ör. bir bildirime yanıt vermek veya mesajı kontrol etmek için) işletim sistemi oyun sürecini arka plana yerleştirir. Oyunun arka plandaki bellekte kaplanan yeri çok yüksekse sistemin düşük bellek durumunda işlem sonlandırma (LMK) özelliği, ön plandaki görevler için RAM'i geri kazanmak amacıyla oyun sürecini sonlandırmaya öncelik verir. Kullanıcı oyuna bir sonraki sefer devam ettiğinde, sorunsuz ve anlık bir sıcak devam ettirme yerine oyunun uzun bir baştan başlatma işleminden geçmesi gerekir. Bu işlemde ağır grafik öğeleri, ses ve oyun motoru ikili programları depolamadan tamamen yeniden yüklenir. Arka plandaki bellek kullanımınızı düşük tutmak, bu sessiz arka plan sonlandırmalarını önler, kullanıcı durumunu korur ve oyuncuların oturumlarına hemen devam etmelerini sağlar. Sistem LMK davranışı hakkında daha fazla bilgi için Android Vitals - Low memory killers (Android Vitals - Düşük bellekli sistemleri kapatma) kılavuzuna bakın.
  • Ekosistem ve cihaz kararlılığı: Belleğin verimsiz kullanımı ve bellek sızıntıları, sistemin genel sağlığını olumsuz etkiler. Sistem belleği azaldığında sistem ciddi bir baskı altında kalır. Bu durum, kare hızının düşmesine, kullanıcı arayüzünün takılmasına ve ses hatalarına neden olur. Bellek baskısı çok şiddetliyse sistemin düşük bellek sorunu gidericisi (LMK), arka plan işlemlerini agresif bir şekilde sonlandırır. Bu durum, oyuncular görevler arasında geçiş yaptığında diğer uygulamaların yavaş soğuk başlatmalar yaşamasına ve kullanıcı durumunu kaybetmesine neden olur.
  • Platform düzeyinde sonlandırmalar: Android 17'den (API düzeyi 37) itibaren sistem, çok fazla bellek kullanan işlemleri sonlandırma konusunda daha proaktif davranır. Oyununuzun kapladığı alan çok yüksekse işletim sistemi, standart bir yığın izi oluşturmadan işlemini aniden sonlandırabilir.
  • Cihaz uyumluluğu: En üst düzey cihazlarda 12 GB ila 16 GB RAM bulunsa da dünya genelindeki oyun kitlesinin büyük bir kısmı 4 GB veya 6 GB RAM'e sahip cihazlar kullanıyor. Doğru bellek yönetimi, karmaşık ve ayrı öğe paketleri gerektirmeden oyununuzun tüm donanım katmanlarında erişilebilir ve duyarlı kalmasını sağlar.

Android'de belleği anlama

Geliştiricilerin etkili bellek bütçelendirme stratejileri tasarlayabilmesi için Android platformunun fiziksel belleği nasıl yönettiğini ve oyununuzun etkin ayak izini nasıl ölçtüğünü anlaması gerekir.

Android'deki temel bellek kavramları

Platform düzeyinde bellek yönetimiyle ilgili temel kavramlar için resmi Bellek Yönetimine Genel Bakış dokümanına bakın. Bu kaynakta dört mimari alan ele alınmaktadır:

  • Belleğe genel bakış: Android, RAM'i yönetmek için sayfalama ve bellek eşleme (mmap) kullanır. Disk üzerinde geleneksel bir takas dosyasını desteklemez. Bunun yerine, fiziksel belleği boşaltmak için sayfa sıkıştırma (zRAM kullanarak) ve sayfa geri kazanımına dayanır.
  • İşlemler arasında bellek ayırma: Android, RAM'i sistem genelinde paylaşır. Dalvik veya ART sanal makine yürütmesi için belirli yığınlar atarken yerel geliştirme ortamlarının (ör. C++ oyun motorları) yerel sistem yığınından bellek istemesine izin verir.
  • Uygulama belleği yönetimi: Çok işlemli bir model altında çalışan Android, uygulamaların yaşam döngüsü durumlarını dinamik olarak izlemesini ve sistemin sağlıklı çalışmasını desteklemek için gereksiz kaynakları (ör. önbelleğe alınmamış grafikler ve bit eşlemler) gönüllü olarak serbest bırakmasını bekler.
  • Süreçlere ve iş parçacıklarına genel bakış: Sistem, süreçleri kullanıcının algıladığı mevcut görünürlük ve önem düzeylerine göre hiyerarşik olarak sınıflandırır. Böylece, düşük bellek koşullarında hangi süreçlerin etkin tutulacağını ve hangilerinin önce sonlandırılacağını belirler.

Toplam bellekte kaplanan yer metriği

Platform düzeyindeki Android 17 bellek sınırlayıcı, işlem tüketimini değerlendirirken toplam kalıcı boyut (RSS) veya sanal bellek boyutu yerine toplam bellek ayak izini kullanır.

Toplam bellek ayak izi = Anonim RSS (RssAnon) + Sıkıştırılmamış Takas (VmSwap)

Geliştiricilerin, oyunların platform tarafından uygulanan sınırları aşmasını önlemek için bu metriklerin sistem düzeyinde tam olarak neyi temsil ettiğini anlaması gerekir. Bu metrikler, fiziksel RAM tahsisleri ve dosya destekli sayfaların nasıl işlendiği hakkında daha fazla bilgi için Bellek Kullanımını İzleme kılavuzundaki RSS ve Takas Metriklerini Anlama bölümüne bakın.

Bellek kısıtlamaları

Sistem kararlılığını korumak ve uygulamaların aşırı kaynak tüketmesini önlemek için Android platformu, çalışan işlemlere bellek sınırları uygular.

Android 17 ve sonraki sürümlerde bellek sınırlayıcı

Android 17 ve sonraki sürümlerde, tek tek uygulamaların sistem genelinde dengesizliğe neden olmasını önlemek için Linux cgroup v2 kullanılarak uygulama başına katı bellek sınırları uygulanır. Teknik uygulama hakkında daha fazla bilgi için AOSP Bellek Sınırlayıcı Kılavuzu ve Bellek Verimliliğine Öncelik Verme: Android 17 İçin Temel Adımlar Blogu'na bakın.

  • Mekanizma: Bellek sınırlayıcı, tüm uygulama işlemlerini izler ve işlemin yaşam döngüsü durumuna göre dinamik olarak sınırlar atar:
    • Görünür işlemler (ön plan): Şu anda kullanıcı arayüzü gösteren uygulama işlemlerinin daha büyük bir kaynak çalışma kümesi çalıştırması beklenir ve bu işlemlere daha yüksek bir sınır uygulanır.
    • Görünür olmayan işlemler (arka plan veya hizmetler): Kullanıcı arayüzü göstermeden aktif olarak çalışan uygulama işlemleri, daha sıkı ve kısıtlayıcı bir bütçeyle sınırlandırılır.
  • Çekirdek özellikleri: Hizmet iki temel özelliğe dayanır:
    • memory.high: Esnek bir sınırdır. Bu sınır aşıldığında çekirdek, işlemi kısıtlar ve belleği agresif bir şekilde geri almaya çalışır. Bu geri alma işlemi, oyunun performansının düşmesine neden olabilir.
    • memory.swap.max: İşlemin kullanabileceği takas veya zRAM alanı için kesin bir sınır uygular.
  • Sonlandırma davranışı: Bir işlem, memory.high'ı aşan anonim bellek ayırmaya devam eder ve takas kapasitesini tüketirse ayırmalar başarısız olur ve işletim sistemi işlemi sessizce sonlandırır. Bu sonlandırma, ApplicationExitInfo kullanılarak Bellek Sınırlayıcı çıkış nedeni altında günlüğe kaydedilir (Android 17, 26Q4'ten itibaren kullanılabilir).

Bellek kullanımını izleme

Oyununuzun belleğini etkili bir şekilde optimize etmek için öncelikle Android platformunun kapladığı alanı nasıl ölçtüğünü anlamanız gerekir. Android 17, dosya destekli veya GPU'ya özel bellek hariç olmak üzere Anonymous RSS (RssAnon) ve sıkıştırılmamış Swap (VmSwap) toplamını izlemek için bellek zorlama metriğini günceller. Bu kılavuzda, Perfetto ve meminfo gibi sistem düzeyindeki araçlardan nasıl yararlanılacağı, ProfilingManager ve onTrimMemory gibi teşhis API'lerinin nasıl uygulanacağı ve Unity ile Unreal Engine'deki kesin bellek ayırmalarının nasıl çıkarılacağı ayrıntılı olarak açıklanmaktadır. Oyununuzun profilini doğru şekilde oluşturmayı ve geleneksel çalışma zamanı belleği yoklamasıyla ilişkili performans takılmalarını önlemeyi öğrenin.

Daha fazla bilgi için Bellek kullanımını izleme başlıklı makaleyi inceleyin.

Bellek azaltma stratejileri

Oyun motorları platformlar arası geliştirmeyi kolaylaştırsa da varsayılan bellek işleme yöntemleri, işletim sistemi düzeyinde bellek sınırlarını tetikleyebilir. Bu sayfada, Unity ve Unreal Engine için özel olarak tasarlanmış pratik optimizasyon adımları ayrıntılı olarak açıklanmaktadır. Java tabanlı onTrimMemory kullanmanın Unity'de neden kilitlenmelere yol açabileceğini ve bunun yerine yerel yaşam döngüsü geri çağırma yöntemlerinin nasıl kullanılacağını öğrenin. Ayrıca, oyununuzun tüm donanım katmanlarında sorunsuz çalışmasını sağlamak için ASTC 8x8 doku sıkıştırmasını kullanma ve öğe kaldırmalarını yapılandırma gibi önemli öğe düzeyinde optimizasyonları da keşfedeceksiniz.