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 izlenmeli ve optimize edilmelidir. Ancak 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 sonlandırıcı (LMK) daemon işlemi, yüksek bellek kullanımına en az gerekli işlemleri sonlandırarak yanıt 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 ön plandaki uygulamayı doğrudan etkileyebilir.
  • Başlatıcıya geçiş önemli ölçüde gecikebilir ve geçiş tamamlanana kadar ön plandaki uygulama yanıt vermiyormuş gibi görünebilir.
  • Sistem, bellek ayırma işlemi beklenirken ileti dizisinin yürütülmesini 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 önemli ölçüde 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ının benzer özellikleri vardır. Bu nedenle, benzer uygulama ve ortak zorluklar söz konusudur. Bu iki durum, diğer cihaz türlerinde ve uygulamalarda görülmeyen sorunlara yol açar:

  • 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 miktarda 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ılavuzda öncelikle uygulama bellek kullanımı ve düşük RAM'li cihazlar için bellek hedefleri ele alınmaktadı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 true 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 bellek kötüye kullanımları 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.

memory profiler

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 bir 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+Takas + Grafik + Dosya) 280 MB.

Aşağıdaki sınırları aşmamanız önemle tavsiye edilir:

  • (Anon+Takas + Grafikler) ü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 belirli ö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 tabanlı 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.

Anonim+Takas belleği

Anon+Swap, Android Studio bellek profil oluşturucusunda Native + Java + Stack ayırmalarından oluşur. Cihazın bellek açısından sınırlı 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ış olmasını önlemek için bölüm değiştirilirken ücretsiz medya belleği ayırma.
    • 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. 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 gelecekteki arabellekte 5 saniyeden fazla yer ayırmayı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:
    • Grafik 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 tahsisleri 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ını yapın. Bu kitaplıklar ek kitaplıklar da yükleyebilir. Bu durum, ayırmalara ve bağlamalar oluşturulmasına da neden olabilir.
  • 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ğlamayı 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 abonelikleri ve satın alma işlemlerini yönetmek 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 her zaman video veya medya oynatmadan önce BillingClient.endConnection() seçeneğini 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() kullanın. İşlem bittikten sonra BillingClient.endConnection() işlemini tekrar yapın.
  • GMS FontsProvider
    • Yazı tiplerini indirmek maliyetli olduğundan ve FontsProvider bunu yapmak için hizmetleri bağlayacağından, düşük RAM'li cihazlarda yazı tipi sağlayıcı kullanmak yerine bağımsız yazı tiplerini 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ılmıştır 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 planda çalışırken ç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:

  • Ses uygulamaları için: Ön plan hizmetlerinin, ses parçasının çalmaya devam etmesi için kullanıcı uygulamadan ayrıldıktan sonra yalnızca çalışmaya devam etmesine izin verilir. Ses çalma işlemi sona erdikten sonra hizmet derhal durdurulmalıdır.
  • Diğer tüm uygulamalar için: Kullanıcı uygulamanızdan ayrıldıktan sonra tüm ön plan hizmetleri durdurulmalıdır. Çünkü uygulamayı kullanıcının fark etmesini sağlayacak bir bildirim yoktur.
  • Önerileri veya Daha Sonra İzle'yi güncelleme gibi arka plan görevleri için WorkManager kullanın.

İş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 sonraki sürümler), kullanılabilir olmadığında ise eski AlarmManager kullanır. TV'de planlanmış işleri gerçekleştirirken en iyi uygulamalar için aşağıdaki önerileri uygulayın:

  • SDK 23 ve sonraki sürümlerde, özellikle AlarmManager.set(), AlarmManager.setExact() ve benzeri yöntemler olmak üzere AlarmManager API'lerini kullanmaktan kaçının. Bu API'ler, sistemin işleri çalıştırmak için uygun zamanı belirlemesine (örneğin, cihaz boşta kaldığında) izin vermez.
  • 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 uygulama geliştirme hakkında genel bilgiler sağlar:

  • Nesne ayırmayı 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 sıkıştırmasının 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ştur'daki LazyList (ör. katalog tarayıcı) veya artık kullanımdan kaldırılan Leanback UI 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, hiçbir zaman serbest bırakılmayan video arabelleklerinin yeniden tahsisi ve benzeri durumlar gibi tipik bellek sızıntısı vakalarına 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 yol açabilir. 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ında sayfaya bellek ayrılması gerekir.

Araç özeti