Bellek kullanımını optimize etme

Bellek optimizasyonu, sorunsuz performans sağlamak, uygulamaların kilitlenmesini önlemek ve sistem kararlılığını ve platform sağlığını korumak için çok önemlidir. Bellek kullanımı her uygulamada izlenip optimize edilmesi gerekse de TV cihazlarına yönelik içerik uygulamaları, elde taşınan cihazlara yönelik tipik Android uygulamalarından farklı zorluklar içerir.

Yüksek bellek tüketimi, uygulama ve sistem davranışlarıyla ilgili sorunlara yol açabilir. Bu sorunlar arasında şunlar yer alır:

  • Uygulamanın kendisi yavaşlayabilir veya gecikebilir ya da en kötü durumda kapatılabilir.
  • Kullanıcı tarafından görülebilen sistem hizmetleri (ses kontrolü, resim ayarları kontrol paneli, sesli asistan vb.) çok yavaşlar veya hiç çalışmayabilir.
  • Düşük bellek durumunda işlem sonlandırma (LMK) arka plan işlemi, yüksek bellek kullanımı durumunda en az gerekli işlemleri sonlandırarak tepki verebilir. Ardından bu bileşenler kısa süre sonra yeniden başlatılabilir ve bu da daha fazla kaynak çekişmesiyle ilgili ani artışlara neden olarak doğrudan ön planda çalışan uygulamayı etkileyebilir.
  • Başlatıcıya geçiş önemli ölçüde gecikebilir ve geçiş tamamlanana kadar ön planda çalışan uygulama yanıt vermiyormuş gibi görünebilir.
  • Sistem, bellek ayırma işlemi beklenirken iş parçacığı yürütmesini geçici olarak durdurarak doğrudan geri alma kullanmaya başlayabilir. Bu durum, ana iş parçacığı veya codec ile ilgili iş parçacıkları gibi herhangi bir iş parçacığında meydana gelebilir. Bu durum, ses ve video karelerinin düşmesine ve kullanıcı arayüzünde aksaklıklara neden olabilir.

TV cihazlarında bellek ile ilgili dikkat edilmesi gereken noktalar

TV cihazları genellikle telefon veya tabletlere kıyasla çok daha az belleğe sahiptir. Örneğin, TV'de görebileceğimiz bir yapılandırma 1 GB RAM ve 1080p video çözünürlüğüdür. Aynı zamanda, çoğu TV uygulamasında benzer özellikler bulunur. Bu nedenle, benzer uygulama ve ortak zorluklar söz konusudur. Bu iki durumda, diğer cihaz türlerinde ve uygulamalarda görülmeyen sorunlar ortaya çıkar:

  • Medya TV uygulamaları genellikle hem ızgara resim görünümleri hem de tam ekran arka plan resimlerinden oluşur. Bu uygulamalar, kısa süre içinde belleğe çok sayıda resim yüklenmesini gerektirir.
  • TV uygulamaları, video ve ses oynatmak için belirli bir miktarda bellek ayrılmasını gerektiren multimedya akışlarını oynatır ve sorunsuz oynatma sağlamak için önemli ölçüde medya arabelleği kullanır.
  • Ek medya özellikleri (arama, bölüm değişikliği, ses parçası değişikliği vb.) düzgün şekilde uygulanmazsa ek bellek baskısı oluşturabilir.

TV cihazlarını anlama

Bu kılavuz öncelikli olarak uygulama bellek kullanımı ve düşük RAM'li cihazlar için bellek hedeflerine odaklanmaktadır.

TV cihazlarında şu özellikleri göz önünde bulundurun:

  • Cihaz belleği: Cihazda yüklü olan rastgele erişim belleği (RAM) miktarı.
  • Cihaz kullanıcı arayüzü çözünürlüğü: Cihazın işletim sistemi ve uygulamalar kullanıcı arayüzünü oluşturmak için kullandığı çözünürlük. Bu çözünürlük genellikle cihazın video çözünürlüğünden düşüktür.
  • Video çözünürlüğü: Cihazın videoları oynatabileceği maksimum çözünürlük.

Bu durum, farklı cihaz türlerinin sınıflandırılmasına ve belleklerinin nasıl kullanılması gerektiğine yol açar.

TV cihazları özeti

Cihaz belleği Cihaz video çözünürlüğü Cihaz kullanıcı arayüzü çözünürlüğü isLowRAMDevice()
1 GB 1080p 720p Evet
1,5 GB 2160p 1080p Evet
≥1,5 GB 1080p 720p veya 1080p Hayır*
≥2 GB 2160p 1080p Hayır*

Düşük RAM'li TV cihazları

Bu cihazlar bellek sınırlı bir durumda ve ActivityManager.isLowRAMDevice() değerini doğru olarak bildirir. Düşük RAM'li TV cihazlarında çalışan uygulamaların ek bellek kontrolü önlemleri uygulaması gerekir.

Aşağıdaki özelliklere sahip cihazlar bu kategoriye girer:

  • 1 GB RAM'li cihazlar: 1 GB RAM, 720p/HD (1280x720) kullanıcı arayüzü çözünürlüğü, 1080p/FullHD (1920x1080) video çözünürlüğü
  • 1,5 GB RAM'li cihazlar: 1,5 GB RAM, 1080p/FullHD (1920x1080) kullanıcı arayüzü çözünürlüğü, 2160p/UltraHD/4K (3840x2160) video çözünürlüğü
  • OEM'nin ek bellek kısıtlamaları nedeniyle ActivityManager.isLowRAMDevice() işaretini tanımladığı diğer durumlar.

Normal TV cihazları

Bu cihazlarda bu kadar önemli bir bellek baskısı durumu yaşanmaz. Bu cihazların aşağıdaki özelliklere sahip olduğunu düşünüyoruz:

  • ≥1,5 GB RAM, 720p veya 1080p kullanıcı arayüzü ve 1080p video çözünürlüğü
  • ≥2 GB RAM, 1080p kullanıcı arayüzü ve 1080p veya 2160p video çözünürlüğü

Ancak bu, uygulamaların bu cihazlardaki bellek kullanımını önemsememesi gerektiği anlamına gelmez. Çünkü belirli belleklerin yanlış kullanımı mevcut belleği tüketebilir ve performansın düşmesine neden olabilir.

Düşük RAM'li TV cihazlarında bellek hedefleri

Bu cihazlarda belleği ölçerken Android Studio bellek profil aracını kullanarak belleğin her bölümünü izlemenizi kesinlikle öneririz. TV uygulamaları, bellek kullanımlarını profillendirmeli ve kategorilerini bu bölümde tanımladığımız eşiklerin altına indirmek için çalışmalıdır.

bellek profil aracı

Bellek nasıl sayılır? bölümünde, bildirilen bellek rakamlarıyla ilgili ayrıntılı bir açıklama bulabilirsiniz. TV uygulamaları için eşiklerin tanımında üç bellek kategorisine odaklanacağız:

  • Anonim + Takas: Android Studio'da Java + Native + Stack allocation memory'den oluşur.
  • Grafikler: Doğrudan profiler aracında bildirilir. Genellikle grafik dokularından oluşur.
  • Dosya: Android Studio'da "Kod" + "Diğerleri" kategorileri olarak bildirilir.

Bu tanımlara göre aşağıdaki tabloda, her bellek grubu türünün kullanması gereken maksimum değer gösterilmektedir:

Bellek türü Purpose Kullanım hedefleri (1 GB)
Anonim + Takas (Java + Yerel + Yığın) Tahsisler, medya arabellekleri, değişkenler ve diğer bellek yoğun görevler için kullanılır. < 160 MB
Grafik GPU tarafından dokular ve ekranla ilgili arabellekler için kullanılır. 30-40 MB
Dosya Bellekteki kod sayfaları ve dosyalar için kullanılır. 60-80 MB

Maksimum toplam bellek (Anon+Takas + Grafik + Dosya) aşağıdakileri aşmamalıdır:

  • 1 GB düşük RAM'li cihazlarda toplam bellek kullanımı (Anon+Swap + Graphics + File) 280 MB olmalıdır.

Aşağıdaki sınırları aşmamanız kesinlikle önerilir:

  • (Anon+Swap + Graphics) üzerinde 200 MB bellek kullanımı.

Dosya belleği

Dosya destekli bellek için genel rehberlik olarak şunları unutmayın:

  • Genel olarak dosya belleği, işletim sistemi bellek yönetimi tarafından iyi bir şekilde işlenir.
  • Şu anda bunun önemli bir bellek baskısı nedeni olduğunu düşünmüyoruz.

Ancak genel olarak Dosya Belleği ile çalışırken:

  • Derlemenize kullanılmayan kitaplıkları eklemeyin ve mümkün olduğunda kitaplıkların tamamı yerine küçük alt kümelerini kullanın.
  • Büyük dosyaları bellekte açık tutmayın ve bu dosyalarla işiniz bittiğinde hemen serbest bırakın.
  • Java ve Kotlin sınıfları için derlenmiş kod boyutunuzu en aza indirin. Uygulamanızı küçültme, karartma ve optimize etme kılavuzuna bakın.

Belirli TV önerileri

Bu bölümde, TV cihazlarında bellek kullanımını optimize etmeye yönelik özel öneriler sunulmaktadır.

Ekran kartı belleği

Uygun resim biçimleri ve çözünürlükleri kullanın.

  • Cihaz kullanıcı arayüzü çözünürlüğünden daha yüksek çözünürlüklü resimler yüklemeyin. Örneğin, 1080p görüntüler 720p kullanıcı arayüzü cihazında 720p'ye küçültülmelidir.
  • Mümkün olduğunda donanım destekli bit eşlemleri kullanın.
    • Glide gibi kitaplıklarda, varsayılan olarak devre dışı olan Downsampler.ALLOW_HARDWARE_CONFIG özelliğini etkinleştirin. Bu ayarın etkinleştirilmesi, aksi takdirde hem ekran kartı belleğinde hem de anonim bellekte bulunacak olan bit eşlemlerin yinelenmesini önler.
  • Ara oluşturma ve yeniden oluşturma işlemlerinden kaçının
    • Bunlar Android GPU Inspector ile tanımlanabilir:
    • "Doku" bölümünde, yalnızca son oluşturmayı oluşturan öğeler olmak yerine son oluşturmaya yönelik adımlar olan resimleri arayın. Bu resimler genellikle "ara oluşturma" olarak adlandırılır.
    • Android SDK uygulamalarında, bu düzen için ara oluşturmaları devre dışı bırakmak üzere layout işareti forceHasOverlappedRendering:false kullanılarak bunlar genellikle kaldırılabilir.
    • Çakışan Oluşturmalardan Kaçınma başlıklı makaleyi inceleyerek çakışan oluşturmalarla ilgili harika bir kaynak edinebilirsiniz.
  • Mümkün olduğunda yer tutucu resim yüklemekten kaçının. Yer tutucu dokular için @android:color/ veya @color kullanın.
  • Kompozisyon çevrimdışı olarak gerçekleştirilebiliyorsa cihazda birden fazla görüntüyü birleştirmekten kaçının. İndirilen resimlerden resim kompozisyonu oluşturmak yerine bağımsız resimleri yüklemeyi tercih edin.
  • Bit eşlemleri daha iyi işlemek için Bit eşlemleri işleme kılavuzunu inceleyin.

Anon+Swap memory

Anon+Swap, Android Studio'daki Native + Java + Stack bellek ayırmalarından oluşur. Cihazın bellek sınırlaması olup olmadığını kontrol etmek ve bu duruma uyum sağlamak için ActivityManager.isLowMemoryDevice() bu yönergeleri uygulayın.

  • Medya:
    • Cihazın RAM'ine ve video oynatma çözünürlüğüne bağlı olarak medya arabellekleri için değişken bir boyut belirtin. Bu, 1 dakikalık video oynatma süresine karşılık gelir:
      1. 1 GB / 1080p için 40-60 MB
      2. 1,5 GB / 1080p için 60-80 MB
      3. 1,5 GB / 2160p için 80-100 MB
      4. 2 GB / 2160p için 100-120 MB
    • Anonim bellek toplam miktarında artışları önlemek için bölüm değiştirilirken ücretsiz medya belleği ayırmaları.
    • Uygulamanız durdurulduğunda medya kaynaklarını hemen serbest bırakın ve durdurun: Ses ve video kaynaklarını işlemek için etkinlik yaşam döngüsü geri çağırmalarını kullanın. Bir ses uygulaması değilseniz etkinliklerinizde onStop() gerçekleştiğinde oynatmayı durdurun, yaptığınız tüm çalışmaları kaydedin ve kaynaklarınızı serbest bırakılacak şekilde ayarlayın. Daha sonra ihtiyacınız olabilecek işleri planlamak için İşler ve Alarmlar bölümüne bakın.
    • Video ararken arabelleğin belleğine dikkat edin: Geliştiriciler, videoyu kullanıcıya hazır hale getirmek için arama yaparken genellikle 15-60 saniye daha fazla içerik ayırır ancak bu, ek bellek yükü oluşturur. Genel olarak, kullanıcı yeni video konumunu seçene kadar 5 saniyeden fazla gelecekteki arabellek kullanmayın. Arama yaparken kesinlikle ek süre önbelleğe almanız gerekiyorsa:
      • Arama arabelleğini önceden ayırın ve yeniden kullanın.
      • Arabellek boyutu 15-25 MB'tan büyük olmamalıdır (cihaz belleğine bağlı olarak).
  • Ayrılanlar:
    • Ekran kartı belleği kılavuzunu kullanarak Anonim bellekteki görüntüleri kopyalamadığınızdan emin olun.
      • Görüntüler genellikle belleği en çok kullanan öğelerdir. Bu nedenle, görüntülerin yinelenmesi cihaz üzerinde büyük bir baskı oluşturabilir. Bu durum özellikle resim ızgarası görünümlerinde yoğun gezinme sırasında geçerlidir.
    • Ekranları taşırken referanslarını bırakarak ayırmaları serbest bırakın: Bit eşlemlere ve geride kalan nesnelere referans olmadığından emin olun.
  • Kitaplıklar:
    • Yeni kitaplıklar eklerken kitaplıklardan profil bellek ayırmaları yapın. Çünkü bu kitaplıklar ek kitaplıklar da yükleyebilir. Bu durum, ayırmalara da neden olabilir ve bağlantılar oluşturabilir.
  • Ağ iletişimi:
    • Uygulama başlatılırken ağ çağrılarını engellemeyin. Bu çağrılar, uygulama başlatma süresini yavaşlatır ve başlatma sırasında ek bellek yükü oluşturur. Bu sırada bellek, uygulama yükü nedeniyle özellikle sınırlıdır. Önce bir yükleme veya başlangıç ekranı gösterin ve kullanıcı arayüzü hazır olduğunda ağ isteklerini yapın.

Bağlamalar

Bağlamalar, diğer uygulamaları belleğe getirdiği veya API çağrısını kolaylaştırmak için bağlı uygulamanın bellek tüketimini artırdığı (zaten bellekteyse) için ek bellek yükü getirir. Bu durum, sonuç olarak ön planda çalışan uygulamanın kullanılabilir belleğini azaltır. Bir hizmeti bağlarken bağlamayı ne zaman ve ne kadar süreyle kullandığınıza dikkat edin. Gerekmediğinde bağlantıyı serbest bıraktığınızdan emin olun.

Tipik bağlamalar ve en iyi uygulamalar:

  • Play Integrity API: Cihaz bütünlüğünü kontrol etmek için kullanılır.
    • Yükleme ekranından sonra ve medya oynatılmadan önce cihaz bütünlüğünü kontrol etme
    • İçerik oynatılmadan önce PlayIntegrity'ye StandardIntegrityManager referansları yayınlayın.
  • Play Faturalandırma Kitaplığı: Google Play kullanılarak yapılan aboneliklerin ve satın alma işlemlerinin yönetilmesi için kullanılır.
    • Kitaplığı yükleme ekranından sonra başlatın ve herhangi bir medya oynatmadan önce tüm faturalandırma işlemlerini gerçekleştirin.
    • Kitaplığı kullanmayı bitirdiğinizde ve video ya da medya oynatmadan önce her zaman BillingClient.endConnection() simgesini kullanın.
    • Herhangi bir faturalandırma işleminin tekrar yapılması gerekirse hizmetin bağlantısının kesilip kesilmediğini kontrol etmek için BillingClient.isReady() ve BillingClient.getConnectionState() seçeneklerini kullanın. İşlem bittikten sonra BillingClient.endConnection() işlemini tekrar yapın.
  • GMS FontsProvider
    • Fontları indirmek maliyetli olduğundan ve FontsProvider bunu yapmak için hizmetleri bağlayacağından, düşük RAM'li cihazlarda font sağlayıcı kullanmak yerine bağımsız fontları kullanmayı tercih edin.
  • Google Asistan kitaplığı: Bazen arama ve uygulama içi arama için kullanılır. Mümkünse bu kitaplığı değiştirin.
    • Leanback uygulamaları için: Gboard'da metin okuma özelliğini veya androidx.leanback kitaplığını kullanın.
      • Aramayı uygulamak için Arama yönergelerini uygulayın.
      • Not: leanback kullanımdan kaldırıldı ve uygulamalar TV Compose'a taşınmalıdır.
    • Compose uygulamaları için:
      • Sesli aramayı uygulamak için Gboard'un metin okuma özelliğini kullanın.
    • Uygulamanızdaki medya içeriklerinin keşfedilebilir olması için Sonraki İzle özelliğini uygulayın.

Ön Plan Hizmetleri

Ön plan hizmetleri, bildirime bağlı özel bir hizmet türüdür. Bu bildirim, telefon ve tabletlerdeki bildirim tepsisinde gösterilir. Ancak TV cihazlarında bu cihazlardakiyle aynı anlamda bir bildirim tepsisi yoktur. Ön plan hizmetleri, uygulama arka plandayken çalışmaya devam edebildiği için faydalı olsa da TV uygulamalarının aşağıdaki yönergelere uyması gerekir:

Android TV ve Google TV'de, ön plan hizmetlerinin kullanıcı uygulamadan çıktıktan sonra çalışmaya devam etmesine yalnızca aşağıdaki durumlarda izin verilir:

İşler ve Alarmlar

WorkManager Arka planda tekrarlanan işleri planlamak için kullanılan en yeni Android API'sidir. WorkManager, kullanılabilir olduğunda yeni JobScheduler (SDK 23+) ve kullanılabilir olmadığında eski AlarmManager öğesini kullanır. TV'de planlanmış işleri gerçekleştirirken en iyi uygulamalar için aşağıdaki önerileri uygulayın:

  • AlarmManager API'lerini SDK 23 ve sonraki sürümlerde kullanmaktan kaçının. Özellikle AlarmManager.set(), AlarmManager.setExact() ve benzeri yöntemler, sistemin işleri çalıştırmak için uygun zamanı belirlemesine (örneğin, cihaz boşta kaldığında) izin vermediğinden bu yöntemleri kullanmaktan kaçının.
  • RAM'i düşük olan cihazlarda kesinlikle gerekli olmadığı sürece iş çalıştırmaktan kaçının. Gerekirse WorkManager'ı WorkRequest yalnızca oynatma işleminden sonra önerileri güncellemek için kullanın ve bunu uygulama hâlâ açıkken yapmaya çalışın.
  • Sistemin, işlerinizi uygun zamanda çalıştırmasına izin vermek için WorkManager'ı Constraints tanımlayın:

Kotlin

Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresStorageNotLow(true)
    .setRequiresDeviceIdle(true)
    .build()

Java

Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresStorageNotLow(true)
    .setRequiresDeviceIdle(true)
    .build()
  • İşleri düzenli olarak çalıştırmanız gerekiyorsa (ör. Sonraki İzle özelliğini kullanıcının başka bir cihazdaki uygulamanızda içerik izleme etkinliğine göre güncellemek için) işin bellek tüketimini 30 MB'ın altında tutarak bellek kullanımını düşük tutun.

Bellekle ilgili genel bilgiler

Aşağıdaki yönergeler, Android uygulaması geliştirme hakkında genel bilgiler sağlar:

  • Nesne ayırmalarını en aza indirin, nesnelerin yeniden kullanımını optimize edin ve kullanılmayan nesneleri hemen serbest bırakın.
    • Nesnelere, özellikle de bit eşlemlere referans tutmayın.
    • System.gc() ve doğrudan bellek serbest bırakma çağrılarını kullanmaktan kaçının. Bu çağrılar, sistemin bellek işleme sürecine müdahale eder. Örneğin, zRAM kullanan cihazlarda gc() için zorunlu bir çağrı, belleğin sıkıştırılması ve açılması nedeniyle bellek kullanımını geçici olarak artırabilir.
    • Görünümleri yeniden kullanmak ve liste öğelerini yeniden oluşturmamak için, Oluşturma'daki LazyList (ör. katalog tarayıcı) veya artık kullanımdan kaldırılan Leanback kullanıcı arayüzü araç setindeki RecyclerView gibi öğeleri kullanın.
    • Harici içerik sağlayıcılardan okunan ve değişme olasılığı düşük olan öğeleri yerel olarak önbelleğe alın ve ek harici bellek ayrılmasını önleyen güncelleme aralıkları tanımlayın.
  • Olası bellek sızıntılarını kontrol edin.
    • Anonim iş parçacıklarındaki referanslar, video arabelleklerinin yeniden tahsis edilip hiçbir zaman serbest bırakılmaması gibi tipik bellek sızıntısı durumlarına ve benzerlerine karşı dikkatli olun.
    • Bellek sızıntılarında hata ayıklamak için yığın dökümü kullanın.
  • Uygulamanızı sıfırdan başlatırken anında derleme miktarını en aza indirmek için temel profiller oluşturun.

Doğrudan bellek geri kazanımını anlama

Bir Android TV uygulaması bellek istediğinde ve sistem baskı altındayken Android'in temelini oluşturan Linux çekirdeğinin doğrudan bellek geri kazanımı kullanması gerekebilir.

Bu süreçte, boşaltılan bellek sayfalarını beklemek için tüm ayırma iş parçacıkları tamamen duraklatılır. Bu durum, arka planda geri kazanma işlemi yeterli bellek havuzunu proaktif olarak koruyamadığında ortaya çıkar.

Sistem, yeterli bellek sağlanana kadar iş parçacıklarını ayırmayı duraklattığı için bu durum, kullanıcı deneyiminde fark edilebilir duraklamalara veya takılmalara neden olabilir. Bu bağlamda, iş parçacıklarının ayrılması malloc() gibi uygulama kodu çağrılarıyla sınırlı değildir. Örneğin, kod sayfalarındaki sayfaya bellek ayrılması gerekir.

Araç özeti