Bellek optimizasyonu, Android'de istikrarlı ve yüksek performanslı oyun deneyimleri sunmak için kritik öneme sahiptir. Bu kılavuzda, bellek verimliliğinin neden önemli olduğu, Android işletim sisteminin işlem bellek sınırlarını nasıl yönettiği ve oyununuzun teknik kalitesini izleyip iyileştirmenize yardımcı olacak Google Play Console'daki yeni bellek metrikleri hakkında genel bilgiler verilmektedir.
Bellek optimizasyonunun önemi
Oyununuzun belleğini optimize etmek, oyuncuları elde tutmak, cihaz uyumluluğunu artırmak ve platform kalite standartlarına uymak için çok önemlidir:
- Soğuk başlatmayı önleme (kullanıcı deneyimi ve elde tutma): Bir oyuncu geçici olarak oyununuzdan başka bir uygulamaya geçtiğinde (örneğin, bir bildirimi yanıtlamak veya mesajı kontrol etmek için) işletim sistemi, oyun işlemini arka plana alır. Oyunun arka planda bellekte kapladığı yer çok fazlaysa sistemin Düşük Bellek Sonlandırıcısı (LMK), ön plan görevleri için RAM'i geri almak amacıyla oyun işlemini sonlandırmaya öncelik verir. Kullanıcı oyuna devam ettiğinde, sorunsuz ve anında gerçekleşen bir sıcak devam yerine oyunun uzun bir soğuk başlatma sürecinden geçmesi gerekir. Bu süreçte, ağır grafik öğeleri, sesler ve oyun motoru ikili dosyaları depolama alanından tamamen yeniden yüklenir. Arka plan 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 edebilmesini sağlar. Sistem LMK davranışı hakkında daha fazla bilgi için Android vitals - Düşük bellek sonlandırıcılar kılavuzuna bakın.
- Ekosistem ve cihaz kararlılığı: Verimsiz bellek kullanımı ve bellek sızıntıları, sistem sağlığını genel olarak olumsuz etkiler. Sistem belleği yetersiz olduğunda sistem ciddi bir baskı altında kalır. Bu da kare hızının düşmesine, kullanıcı arayüzünün takılmasına ve ses sorunlarına neden olur. Bellek baskısı çok fazlaysa sistemin Low Memory Killer (LMK) özelliği, arka plan işlemlerini agresif bir şekilde sonlandırır. Bu da diğer uygulamaların yavaş soğuk başlatma yaşamasına ve oyuncular görevler arasında geçiş yaparken kullanıcı durumunun kaybolmasına 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 ayak izi çok yüksekse işletim sistemi, standart bir yığın izleme (stack trace) oluşturmadan oyunun işlemini aniden sonlandırabilir.
- Cihaz uyumluluğu: Amiral gemisi cihazlarda 12 GB ila 16 GB RAM bulunurken dünya genelindeki oyun kitlesinin büyük bir kısmı 4 GB veya 6 GB RAM'e sahip cihazlar kullanır. Doğru bellek yönetimi, oyununuzun karmaşık ve ayrı öğe paketleri gerektirmeden tüm donanım katmanlarında erişilebilir ve duyarlı kalmasını sağlar.
Android'de bellek kullanımı
Geliştiriciler, etkili bellek bütçeleme stratejileri tasarlamak için Android platformunun fiziksel belleği nasıl yönettiğini ve oyununuzun etkin ayak izini nasıl ölçtüğünü anlamalıdır.
Android bellek yönetimiyle ilgili temel kavramlar
Platform düzeyinde bellek yönetimiyle ilgili temel kavramlar için resmi Bellek Yönetimine Genel Bakış dokümanları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. Diskte geleneksel bir takas dosyasını desteklemez. Bunun yerine, fiziksel bellekte yer açmak için sayfa sıkıştırma (zRAM kullanarak) ve sayfa geri kazanma yöntemlerini kullanır.
- İşlemler arasında bellek ayırma: Android, RAM'i tüm sistemde paylaşır. Dalvik veya ART sanal makine yürütme için belirli yığınlar atarken yerel geliştirme ortamlarının (C++ oyun motorları gibi) yerel sistem yığınından bellek istemesine olanak tanır.
- Uygulama bellek yönetimi: Çoklu işlem modeliyle çalışan Android, uygulamaların yaşam döngüsü durumlarını dinamik olarak izlemesini ve sistem sağlığını desteklemek için gereksiz kaynakları (ör. önbelleğe alınmamış grafikler ve bitmap'ler) gönüllü olarak serbest bırakmasını bekler.
- İşlemlere ve iş parçacıklarına genel bakış: Sistem, işlemleri mevcut kullanıcı tarafından algılanan görünürlüklerine ve önemlerine göre bir hiyerarşide kategorilere ayırır. Böylece, düşük bellek koşullarında hangi işlemlerin canlı tutulacağını ve hangilerinin önce sonlandırılacağını belirler.
Bellekte kaplanan toplam yer metriği
Platform düzeyindeki Android 17 Bellek Sınırlayıcı, toplam yerleşik boyut (RSS) veya sanal bellek boyutu yerine toplam bellekte kaplanan yeri kullanarak işlem tüketimini değerlendirir.
Bellekte Kaplanan Toplam Yer = Anonim RSS (RssAnon) + Sıkıştırılmamış Takas (VmSwap)
Oyunların platform sınırlarını aşmasını önlemek için bu metriklerin sistem düzeyinde tam olarak neyi temsil ettiğini anlamanız gerekir. Bu metrikler, fiziksel RAM ayırmaları 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ı
Android platformu, sistem kararlılığını korumak ve uygulamaların aşırı kaynak tüketmesini önlemek için çalışan işlemlerin bellek sınırlarını yönetir.
Android 17 ve sonraki sürümlerde Bellek Sınırlayıcı
Android 17 (API düzeyi 37) ve sonraki sürümler, her bir uygulamanın sistem genelinde kararsızlığa neden olmasını önlemek için Linux cgroup v2'yi kullanarak uygulama başına katı bellek sınırları uygular. Teknik uygulama hakkında daha fazla bilgi için AOSP Bellek Sınırlayıcı Kılavuzu'nu ve Bellek Verimliliğine Öncelik Verme: Android 17 İçin Temel Adımlar Blogu'nu inceleyin.
- 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 grubu çalıştırması beklenir ve daha geniş bir sınır tanınır.
- Görünür olmayan işlemler (arka plan veya hizmetler): Kullanıcı arayüzü göstermeden etkin çalışma yapan uygulama işlemleri, daha sıkı ve daha kısıtlayıcı bir bütçeyle sınırlandırılır.
- Çekirdek özellikleri: Hizmet iki ana ö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 üst sınır belirler.
- Sonlandırma davranışı: Bir işlem,
memory.highdeğerini aşan anonim bellek ayırmaya devam eder ve takas kapasitesini tüketirse ayırma işlemleri başarısız olur ve işletim sistemi, işlemi sessizce sonlandırır. Bu sonlandırma, Bellek Sınırlayıcı çıkış nedeni altındaApplicationExitInfokullanılarak günlüğe kaydedilir (Android 17, 26Q4'ten itibaren kullanılabilir).
Play Console Vitals'da yeni bellek sınırları
Google Play, geliştiricilerin bellek sorunlarını proaktif bir şekilde tespit etmelerine yardımcı olmak için Google Play Console Android vitals'da yeni metrikler sunuyor. Google Play Console, aşırı uç değerleri belirlemek için oyun oturumlarınızın 90. yüzdelik dilimdeki (P90) anonim RSS + takas bellek kullanımını izler.
Uyarı ve yaptırım eşikleri, cihazın fiziksel RAM kapasitesine ve işlem durumlarına göre ölçeklendirilir. Bu sınırlar iki farklı aşamada uygulanır.
Ayrıntılı yönergeler ve bellek sınırları için Android vitals - "Kötü davranış eşikleri nelerdir?" başlıklı makaleyi inceleyin.
Kullanıcı tarafından algılanan hizmetler
Algılanabilir hizmetler, Android sisteminin kullanıcı tarafından fark edilebilir olarak kabul ettiği kritik arka plan işlemleridir. Bu durum, çalışan tüm işlemleri kapsar:
- Ön plan hizmetleri (FGS)
- Yüksek öncelikli işler
- Kullanıcı tarafından başlatılan veri aktarımı işleri
- Sisteme bağlı hizmetler veya diğer uygulamalar tarafından bağlanan hizmetler
Algılanabilir hizmetler, arka planda kritik ve uzun süreli görevler için tasarlandığından kümülatif yaşam döngüsü sızıntılarına karşı son derece hassastır. Android platformu bellek sınırları, bu durumu ön plan olarak değerlendirmez. Yani oyununuz arka planda çalışırken fark edilebilir bir hizmeti çalıştırmaya devam ederse Google Play Yardım Merkezi sayfasında gösterilen daha sıkı arka plan veya hizmet bellek sınırlarına tabi olur. Oyunlar, ön plandan arka plandaki fark edilebilir hizmet durumuna geçerken gereksiz öğeleri agresif bir şekilde kırpmalıdır.
R8 gereksinimleri
Google Play Console, bayt kodu boyutunu ve temel Java işlemi ek yükünü en aza indirmek için uygulama kalitesi yönergeleri kapsamında kod optimizasyonunu değerlendirir. Oyunlar için geçerli olan optimizasyon şartları ve sınırları hakkında daha fazla bilgi edinmek istiyorsanız Android vitals belgelerindeki DEX kodu optimizasyonu bölümüne bakın.
Standart bir Android projesinde R8'i yapılandırmak için Uygulama optimizasyonunu etkinleştirme kılavuzunu inceleyin. Gelişmiş küçültme ve optimizasyon ayarlarını etkinleştirmek için R8'i tam modda kullanma başlıklı makaleyi inceleyin. R8'in sınıfları gizlemesini veya kullanılmayan kodları kaldırmasını engelleyen kuralları belirlemek için R8 Yapılandırma Analiz Aracı'nı kullanın.
Bir oyun motoruyla uygulama geliştiriyorsanız varsayılan R8 davranışı, motora ve sürüme göre değişiklik gösterir:
- Unity: Kod sadeleştirme varsayılan olarak devre dışıdır. Bu nedenle, proje ayarlarınızda bu özelliği etkinleştirmeniz gerekir. Sürüm desteği ve yapılandırma adımları hakkında daha fazla bilgi için R8 ile Unity kodunu küçültme ve optimize etme başlıklı makaleyi inceleyin.
- Unreal Engine: UE 4.25'ten itibaren R8, yayınlanan derlemelerde varsayılan olarak etkinleştirilir. Bu nedenle, JNI köprüleri ve eklentileri için saklama kurallarını yönetmeniz gerekir. Sürüm ayrıntıları ve UPL yapılandırması hakkında daha fazla bilgi için R8 ile Unreal Engine kodunu küçültme ve optimize etme başlıklı makaleyi inceleyin.
Bitmap gereksinimleri
Bit eşlemler, modern yüksek kaliteli oyunlarda bellek kullanımının büyük bir kısmını oluşturur. Bitmap piksel verileri doğrudan Android 8.0 (API düzeyi 26) ve sonraki sürümlerde yönetilmeyen yerel yığında depolandığından, optimize edilmemiş resim yükleme işlemleri platform bellek eşiklerini aşabilir. Resim ölçeklendirme ve önbelleğe alma ile ilgili en iyi uygulamalar için Resim kullanımını optimize etme başlıklı makaleyi inceleyin.
Bellek kullanımını izleme
Oyununuzun belleğini etkili bir şekilde optimize etmek için öncelikle Android platformunun bellek kullanımını nasıl ölçtüğünü anlamanız gerekir. Android 17, bellek metriğini güncelleyerek
dosya destekli veya GPU'ya özel bellek hariç olmak üzere anonim RSS (RssAnon) ve sıkıştırılmamış
takas (VmSwap) toplamını izler. Bu kılavuzda Perfetto ve meminfo gibi sistem düzeyindeki araçların nasıl kullanılacağı, ProfilingManager ve onTrimMemory gibi teşhis API'lerinin nasıl uygulanacağı ve Unity ile Unreal Engine'de hassas 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ı bellek 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 kullanımını azaltma stratejileri
Oyun motorları, platformlar arası geliştirmeyi kolaylaştırsa da varsayılan bellek yönetimi, 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 kilitlenmelere neden olabileceğini ve bunun yerine yerel yaşam döngüsü geri çağırma yöntemlerini nasıl kullanacağınızı öğrenin. Ayrıca, oyununuzun tüm donanım katmanlarında sorunsuz çalışmasını sağlamak için ASTC 8x8 doku sıkıştırmayı kullanma ve öğe boşaltmaları yapılandırma gibi öğe düzeyinde önemli optimizasyonları da keşfedeceksiniz.
Daha fazla bilgi için Bellek kullanımını azaltma başlıklı makaleyi inceleyin.