Oyununuzun bellekte kapladığı yeri etkili bir şekilde optimize etmek için öncelikle Android platformunun belleği nasıl ölçtüğünü ve sistem telemetrisini, teşhis API'lerini ve profil oluşturma araçlarını nasıl kullanacağınızı anlamanız gerekir. Bu kılavuzda, yeni platform yönergeleri kapsamında oyununuzun bellek ayırmalarını nasıl izleyeceğiniz, yakalayacağınız ve analiz edeceğiniz ayrıntılı olarak açıklanmaktadır.
RSS ve takas metriklerini anlama
Oyununuzun bellek davranışını etkili bir şekilde analiz edip hatalarını ayıklamak için Android platformunun bellek zorlama için kullandığı tam teknik metrikleri anlamanız gerekir. Bu telemetri parametresinin gerçek hayatta nasıl işlendiği ve izlendiği hakkında ayrıntılı arka plan bilgisi için Android Vitals - Memory usage (anonymous RSS + swap) (Android Vitals - Bellek kullanımı [anonim RSS + takas]) dokümanına bakın.
1. Anonim RSS (RssAnon)
Kalıcı küme boyutu (RSS), bir işlem tarafından kullanılan ve cihazın fiziksel RAM'inde tutulan bellek bölümünü ölçer. RSS, dosya destekli bellek ve anonim bellek olarak ikiye ayrılır. Android'in yaptırım metriği yalnızca anonim RSS'ye odaklanır:
- İçerdiği öğeler: Doğrudan oyun süreciniz tarafından ayrılan ve depolamadaki fiziksel bir dosyayla bağlantılı olmayan bellek sayfaları. Bu sayfalarda Java veya Kotlin yığınları, iş parçacığı yürütme yığınları ve en önemlisi yerel bellek ayırmaları (ör. özel C++ motoru ayırıcıları veya yerel malloc ya da new kullanılarak istenen ve oyun mantığı tarafından kirletilen bellek blokları) bulunur. Bu metrik hakkında daha fazla bilgiyi İşlem Belleği (RSS) sözlüğünde bulabilirsiniz.
- Önemi: Oyun motorları, fizik, oluşturma ve mantığı işlemek için büyük yerel bellek havuzları kullanır. Bu havuzlar dosyalarla desteklenmediğinden tamamen Anonymous RSS'de bulunur ve oyununuzun fiziksel yer kaplama alanının büyük bir kısmını oluşturur.
2. Sıkıştırılmamış takas (VmSwap)
Android, flash depolama alanının yıpranması ve gecikme kısıtlamaları nedeniyle geleneksel disk tabanlı takas alanını desteklemez. Bunun yerine zRAM (sıkıştırılmamış takas) kullanılır:
- İçerdiği öğeler: Fiziksel RAM basıncı arttığında çekirdeğin bellek yönetimi arka plan programı, etkin olmayan anonim sayfaları sıkıştırır ve fiziksel RAM'in (zRAM) sıkıştırılmamış özel bir bölümüne taşır.
- Metrik hesaplama: Sistem, oyunun gerçek fiziksel bellek talebini değerlendirmek için bu metriği sıkıştırılmamış boyuta (VmSwap) göre izler. Oyununuz bellek ayırırsa ve sistem bunu zRAM'e aktarırsa bu bellek, oyununuzun toplam bellek ayak izine dahil edilir.
3. İşlem durumları
Bellek kullanımı, Android Vitals'da işlem durumlarına göre ayrılır. Oyun geliştiriciler için üçüncü taraf SDK'ları veya oyunları da kullanıcı tarafından algılanan hizmetleri ya da arka plan hizmetlerini beklenmedik şekilde tetikleyebilir.
- Neleri içerir?: Ön plan, algılanabilir hizmetler, arka plan ve önbelleğe alınmış.
- Önemi: Farklı işlem durumları, Android OS bellek yönetimi üzerinde farklı etkilere sahiptir. Üçüncü taraf SDK'lardan herhangi biri arka planda görev başlatırsa oyununuzun hassas bir işlem durumuyla çalıştığını fark etmeyebilirsiniz.
RunningAppProcessInfokullanarak oyununuzun arka planda çalışıp çalışmadığını izleyin.
Uygulama programlama arayüzleri (API'ler)
Android, oyununuzun bellek baskısına dinamik olarak yanıt vermesini ve çalışma zamanında ayrıntılı bellek teşhisleri yakalamasını sağlayan sistem API'leri sunar.
Bellek kırpma etkinliklerine yanıt verme
Sistem, uygulamanızı, yaşam döngüsü etkinlikleri hakkında bilgilendirmek için onTrimMemory kullanır. Bu etkinlikler, 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 sorunu (LMK) tarafından sonlandırılmaktan kaçınması için iyi bir fırsat sunar.
Sistem, uygulamanızı arka planda sonlandırırsa kullanıcı, devam ettirirken yavaş bir sıfırdan başlatma deneyimi yaşar. Arka plan bellek kullanımını azaltmak, bu arka plan sonlandırmalarını önlemeye yardımcı olur.
Kırpma etkinliklerine yanıt verirken, hemen ihtiyaç duyulmayan büyük ve yeniden oluşturulabilir bellek ayırmalarını serbest bırakın:
Örnek:
TRIM_MEMORY_UI_HIDDENyanıtı olarak önbelleğe alınmış bit eşlemleri (yerel depolama alanından kodu çözülmüş) kırpın veya temizleyin.
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.
}
}
}
}
ProfilingManager
Android 15'te (API düzeyi 35) kullanıma sunulan ProfilingManager API, uygulamaların programatik olarak tanımlanan anlık görüntüleri (ör. yığın profilleri, sistem izleri ve Java yığın dökümleri) doğrudan çalışma zamanında yakalamasına olanak tanır.
Geliştiriciler, belirli sahnelerde manuel olarak yakalama tetikleyebilir veya oyun işlemi bellek sınırlayıcı eşiklerini ihlal ettiğinde otomatik olarak yakalama tetiklemek için TRIGGER_TYPE_ANOMALY gibi otomatik tetikleyiciler kaydedebilir. Ancak oyun geliştiriciler, modern oyun motorlarındaki önemli sınırlamaları dikkate almalıdır:
Not: Modern oyun motorları (ör. Unity veya Unreal), MAP_ANONYMOUS işaretiyle mmap kullanarak çekirdekten büyük sanal bellek bloklarını önceden ayırarak yürütme performansını yönetir. Ardından motorlar, bellek bloklarını dahili olarak alt bölümlere ayırmak ve tahsis etmek için özel alt ayırıcılar (ör. Unity'nin yerel bellek yöneticisi veya Unreal'ın BinnedAllocators'ı) kullanır.
ApplicationExitInfo
Oyununuz arka planda sonlandırılırsa veya bireysel işlem belleği sınırlarını ihlal ettiği için kapatılırsa standart Java veya yerel kilitlenme dökümü mekanizmaları (ör. Firebase Crashlytics) etkinliği kaydetmez. Geliştiriciler, bu sonlandırmaları programlı bir şekilde sorgulamak ve günlüğe kaydetmek için oyun başlatılırken ApplicationExitInfo API'sinden yararlanmalıdır.
- Uygulama: Başlangıçta, son oturumların çıkış nedenlerini almak için
ActivityManager.getHistoricalProcessExitReasons()işlevini çağırın. - Bellek uygulamasından çıkışın temel nedenleri:
REASON_LOW_MEMORY: İşlemin, sistemin düşük bellek sorunu (LMK) tarafından sonlandırıldığını gösterir. Bu sonlandırma, cihaz genelinde bellek baskısı yüksek olduğunda ve işletim sisteminin RAM'i geri kazanması gerektiğinde gerçekleşir. Bu çıkış nedeni, oyununuzun arka plan kapladığı alanın diğer uygulamalarla birlikte çalışamayacak kadar büyük olduğunu gösterir.REASON_MEMORY_LIMITER(Android 17 (API düzeyi 37) ve sonraki sürümler): İşlemin, platformun bellek sınırlayıcısı tarafından atanan cgroup bellek sınırını (RssAnon + VmSwap) aştığı için özellikle sonlandırıldığını gösterir. Bu sonlandırma, cihazda yeterli fiziksel bellek kalsa bile gerçekleşebilir. Bu durum, bireysel işlem sınırlarının doğrudan ihlal edildiğini gösterir.
Mevcut araçları kullanma
Geliştirme ve kalite güvencesi sırasında oyununuzun bellek kullanımını doğru bir şekilde ölçmek için aşağıdaki platform araçlarını kullanın.
meminfo
Bu araç, PSS belleğinin ne kadarının 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-namekomutunu kullanın.- Android Debug API'den
MemoryInfoçağrısını kullanın.
PrivateDirty istatistiği, işlemdeki diske aktarılamayan ve başka işlemlerle paylaşılmayan RAM miktarını gösterir. Bu tutarı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ğundan RSS, bellek boyutundaki değişiklikleri daha ayrıntılı göstererek en yüksek bellek kullanımının daha doğru ölçülmesini sağlar. Bu nedenle, oyunun yetersiz belleğe neden olabilecek zirveleri fark etmek daha kolaydır.
Perfetto
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 ürettiği veriler üzerinde SQL sorguları da yayınlayabilirsiniz. Sistem Takibi uygulamasından uzun izlemeleri etkinleştirin. İzleme için memory:Memory kategorisinin etkinleştirildiğinden emin olun. Geliştirme ve test aşamasında özel bellek enstrümantasyonu için (Beta) heapprofd API'yi de kullanabilirsiniz.
RssAnon'u inceleyin ve Perfetto'yu kullanın
Oyununuzun anonim bellek ve zRAM takas etkisini kontrol etmek için izleme dosyanızı ui.perfetto.dev adresindeki web tabanlı kullanıcı arayüzüne yükleyin ve derin bellek çalışmaları için tasarlanmış şu analiz tekniklerini uygulayın (daha fazla bilgi için Perfetto Bellek Analizi Çalışmaları'na bakın):
1. Zaman Çizelgesi'ndeki Bellek Sayaçlarını Görselleştirme
- İşleminizi bulun: Gezinme listesinde oyununuzun paket veya işlem adını arayın.
- Parça grubunu genişletme: İşlem satırınızı tıklayarak ileti dizisi parçalarını genişletin ve Bellek adlı alt grubu bulun.
- Parçaları analiz edin:
- mem.rss.anon (Anonim RSS): Bu çizgi grafik, oyununuzun yönetilmeyen bellek havuzları tarafından kullanılan gerçek zamanlı fiziksel RAM'i gösterir. Yüksek ayırma zirvelerini kontrol etmek için sahne yüklemeleri, kullanıcı arayüzü pop-up'ları veya oyun geçişleri sırasında bu zaman çizelgesini izleyin.
- mem.swap (Compressed Swap veya VmSwap): Bu grafik, zRAM'e taşınan bellek bloklarının önceden sıkıştırılmış boyutunu gösterir. Oyun oynarken yüksek takas etkinliği görülmesi, oyununuzun sınırlı bellekli bir cihazda çalıştığını ve sistemin arka plan öğelerini etkin bir şekilde sıkıştırdığını gösterir.
2. SQL Sorgularını Çalıştırma (İz İşleyici) Ayrıntılı çevrimdışı analiz için SQL sorgularını doğrudan Perfetto kullanıcı arayüzü konsolunda çalıştırabilir veya istatistiksel zirveleri hesaplamak için bağımsız İz İşleyici Python kitaplığını kullanabilirsiniz.
Anonim RSS'nin en yüksek tahsisini bulun:
SELECT max(value) / 1024 / 1024 AS max_rss_anon_mb FROM counter JOIN counter_track ON counter.track_id = counter_track.id WHERE counter_track.name = 'mem.rss.anon' AND counter_track.upid IN ( SELECT upid FROM process WHERE name = 'your.game.package.name' );Herhangi bir zaman damgasında RssAnon ve VmSwap'ı ilişkilendirin:
SELECT ts, track.name AS metric_type, value / 1024 / 1024 AS size_mb FROM counter JOIN counter_track track ON counter.track_id = track.id WHERE (track.name = 'mem.rss.anon' OR track.name = 'mem.swap') AND track.upid IN ( SELECT upid FROM process WHERE name = 'your.game.package.name' ) ORDER BY ts ASC;
Android Studio'yu kullanarak izleme dosyalarını inceleme hakkında daha fazla bilgi için Sistem izlemelerini inceleme: İşlem Belleği (RSS) başlıklı makaleyi inceleyin. Komut dosyası oluşturma bellek profilleriyle ilgili ayrıntılar için Yerel ayırmaları kaydetme başlıklı makaleyi inceleyin.
heapprofd
heapprofd, Perfetto'nun bir parçası olan bellek izleme aracıdır. Bu araç, malloc kullanılarak belleğin nerede tahsis edildiğini 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 MallocDebug gibi diğer araçlar gibi performansı etkilemez.
hata raporu
bugreport, oyununuzun yetersiz bellek nedeniyle kilitlenip kilitlenmediğini öğrenmek için kullanılan bir günlük kaydı aracıdır. Aracın çıktısı, logcat kullanmaktan çok daha ayrıntılıdır. Oyununuzun bellek yetersizliği nedeniyle kilitlenip kilitlenmediğini veya LMK tarafından sonlandırılıp sonlandırılmadığını gösterdiği için bellek hata ayıklaması için yararlıdır.
Daha fazla bilgi için Hata raporlarını yakalama ve okuma başlıklı makaleyi inceleyin.
Oyun motoru araçları
Platform düzeyindeki günlükler ve sistem telemetrisi, işletim sistemi eşiklerini ve uyumluluğu izlemek için hayati önem taşırken oyun motoruna özgü araçlar, tahsisleri doğrudan oyun nesnelerinize, komut dosyası davranışlarınıza ve etkin sahne hiyerarşilerinize atfetmenize yardımcı olur.
Unity
Unity Engine ortamında, Unity'nin yerel profil oluşturma araçlarını ve sınıflarını kullanarak Android Anonymous RSS + Swap bellekte kaplanan yerini çalışma zamanında yüksek güvenilirlikle (genellikle gerçek OS düzeyindeki değerlere kıyasla% 10'dan daha az bir varyans göstererek) yakından tahmin edebilirsiniz.
Yapılandırma kuralları ve çalışma zamanı komut dosyaları da dahil olmak üzere adım adım talimatlar için Unity araçlarıyla belleği kontrol etme başlıklı makaleyi inceleyin.
- Unity profiler API'si: Temel motor metriklerini sorgulayarak oyununuzun çalışma zamanındaki yönetilmeyen bellek ayak izini programatik olarak tahmin edebilirsiniz:
- Profiler sınıfını kullanma:
Profiler.GetTotalReservedMemoryLong()veProfiler.GetMonoHeapSizeLong()değerlerini toplayarak toplam bellek ayırmalarını izleyin. ProfilerRecordersınıfını kullanma: Bellek kategorilerini dinamik olarak izleyin. Güvenilir bir temel tahmin oluşturmak için Toplam Ayrılmış Belleği (Release derlemelerinde) getirin veya dosya destekli ekran kartı belleği bileşenlerini çıkarmak için Gfx Ayrılmış Belleği bundan çıkarın (Development derlemelerinde).
- Profiler sınıfını kullanma:
- Unity bellek profil oluşturucu: Bellek sızıntılarını çevrimdışı olarak belirlemek ve hatalarını ayıklamak için bellek anlık görüntüsü yakalayın ve Tüm Bellek bölümünde bulunan Cihazdaki Yerleşik Bellek grafiğini inceleyin. Yaklaşık ayak izini hesaplamak için aşağıdaki kategorilerin toplamlarını toplayın: İzlenmeyen, Android Çalışma Zamanı, Yerel ve Yönetilen.
- zRAM sınırlaması: Belleğin sınırlı olduğu durumlarda Android çekirdeği, etkin olmayan bellek sayfalarını takas alanına (zRAM) sıkıştırabilir. Unity Memory Profiler, işletim sistemi düzeyindeki takas parametrelerini algılayamadığından, yoğun bellek sahnelerinde küçük ayak izi tutarsızlıkları görebilirsiniz. Tahminlerinizi Perfetto ile karşılaştırarak tam değerleri onaylayın.