Bellek optimizasyonu, sorunsuz performans sağlamak, uygulama kilitlenmelerini önlemek, sistem kararlılığını ve platform sağlığını korumak için çok önemlidir. Her uygulamada bellek kullanımının izlenmesi ve optimize edilmesi gerekir. Bununla birlikte, TV'ler için içerik uygulamalarında, el cihazlarına yönelik tipik Android uygulamalarından farklı zorluklar vardır.
Yüksek bellek tüketimi, aşağıdakiler de dahil olmak üzere uygulama ve sistem davranışlarıyla ilgili sorunlara yol açabilir:
- Uygulama yavaşlayabilir, takılabilir veya 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 gecikmeli hale gelir veya hiç çalışmayabilir.
- Düşük bellek sorunu (LMK) arka plan işlemi, en az önemli işlemleri sonlandırarak yüksek bellek basıncına tepki verebilir. Ardından bu bileşenler kısa bir süre sonra yeniden başlatılabilir ve doğrudan ön plan uygulamasını etkileyebilecek daha fazla kaynak çekişmesi sivri uçları tetiklenebilir.
- Başlatıcıya geçiş önemli ölçüde gecikebilir ve geçiş tamamlanana kadar ön plan uygulaması yanıt vermiyormuş gibi görünebilir.
- Sistem, bellek ayırmayı beklerken bir iş parçacığının yürütülmesini geçici olarak duraklatarak doğrudan yeniden alma özelliğini kullanmaya başlayabilir. Bu durum, ana iş parçacığı veya codec ile ilgili iş parçacığı gibi herhangi bir iş parçacığında gerçekleşebilir. Bu da ses ve video karelerinin düşmesine ve kullanıcı arayüzünde aksamalara neden olabilir.
TV cihazlarındaki bellek ile ilgili dikkat edilmesi gereken noktalar
TV cihazları genellikle telefonlara veya tabletlere kıyasla çok daha az belleğe sahiptir. Örneğin, TV'de 1 GB RAM ve 1080p video çözünürlüğü gibi bir yapılandırma görebilirsiniz. Aynı zamanda çoğu TV uygulaması benzer özelliklere sahiptir. Bu nedenle, benzer bir 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 şeklinde resim görünümlerinden hem de kısa süre içinde belleğe çok sayıda resim yüklemeyi gerektiren tam ekran arka plan resimlerinden oluşur.
- TV uygulamaları, video ve ses oynatmak için belirli miktarda bellek ayırmayı gerektiren ve sorunsuz oynatma sağlamak için önemli miktarda medya arabelleğine ihtiyaç duyan multimedya akışları oynatır.
- Düzgün şekilde uygulanmayan ek medya özellikleri (sarma, bölüm değiştirme, ses parçası değiştirme vb.) ek bellek baskısı oluşturabilir.
TV cihazlarını anlama
Bu kılavuzda, öncelikle RAM'i düşük cihazlarda uygulama bellek kullanımı ve bellek hedeflerine odaklanılmıştı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ıdır.
- Cihaz kullanıcı arayüzü çözünürlüğü: Cihazın, işletim sistemini ve uygulama kullanıcı arayüzünü oluşturmak için kullandığı çözünürlüktür. Bu çözünürlük genellikle cihazın video çözünürlüğünden daha düşüktür.
- Video çözünürlüğü: Cihazın video oynatabileceği maksimum çözünürlük.
Bu da farklı cihaz türlerinin ve bu cihazların belleği nasıl kullanması gerektiğinin sınıflandırılmasına yol açar.
TV cihazları özeti
Cihaz belleği | Cihazın 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'e sahip TV cihazları
Bu cihazlar bellek sınırlamalı bir durumdadır ve ActivityManager.isLowRAMDevice()
değerini doğru olarak raporlar. Düşük RAM'e sahip TV cihazlarında çalışan uygulamaların ek bellek kontrol önlemleri uygulaması gerekir.
Aşağıdaki özelliklere sahip cihazlar bu kategoriye girer:
- 1 GB'lık cihazlar: 1 GB RAM, 720p/HD (1280x720) kullanıcı arayüzü çözünürlüğü, 1080p/FullHD (1920x1080) video çözünürlüğü
- 1,5 GB'lık cihazlar: 1,5 GB RAM, 1080p/Full HD (1920x1080) kullanıcı arayüzü çözünürlüğü, 2160p/Ultra HD/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 cihazlar, bu kadar önemli bir bellek baskısı sorunu yaşamaz. Bu cihazların aşağıdaki özelliklere sahip olduğunu kabul ederiz:
- ≥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 bazı belleklerin kötüye kullanılması mevcut belleği tüketmeye devam edebileceği ve kötü performansa neden olabileceği için uygulamaların bu cihazlardaki bellek kullanımını göz ardı etmemesi gerekir.
Düşük RAM'e sahip TV cihazlarındaki bellek hedefleri
Bu cihazlardaki belleği ölçerken Android Studio bellek profilleyicisini kullanarak belleğin her bölümünü izlemenizi önemle tavsiye ederiz. TV uygulamaları, bellek kullanımlarını profillemelidir ve kategorilerini bu bölümde tanımladığımız eşiklerin altına düşürmeye çalışmalıdır.
Bildirilen bellek rakamlarının ayrıntılı açıklamasını Bellek nasıl sayılır? bölümünde bulabilirsiniz. TV uygulamaları için eşiklerin tanımı söz konusu olduğunda üç bellek kategorisine odaklanacağız:
- Anonymous + Swap: Android Studio'da Java + Native + Stack ayırma belleğinden oluşur.
- Grafikler: Doğrudan profilleyici aracında raporlanır. Genellikle grafik dokularından oluşur.
- Dosya: Android Studio'da "Kod" + "Diğer" kategorilerinde bildirilir.
Bu tanımlar doğrultusunda, aşağıdaki tabloda her bellek grubu türünün kullanması gereken maksimum değer gösterilmektedir:
Bellek türü | Amaç | Kullanım hedefleri (1 GB) |
---|---|---|
Anonim + Değişim (Java + Yerel + Yığın) | Ayırma işlemleri, medya arabellekleri, değişkenler ve yoğun bellek kullanan diğer görevler için kullanılır. | < 160 MB |
Grafik | Dokular ve ekranla ilgili arabellekler için GPU tarafından kullanılır | 30-40 MB |
Dosya | Bellekteki kod sayfaları ve dosyalar için kullanılır. | 60-80 MB |
Maksimum toplam bellek (Anon+Swap + Grafik + Dosya) aşağıdakileri aşmamalıdır:
- 1 GB RAM'e sahip düşük RAM'li cihazlar için toplam 280 MB bellek kullanımı (Anonim+Takas + Grafik + Dosya).
Aşağıdaki değerleri aşmamanız önemle tavsiye edilir:
- (Anon+Swap + Graphics) 200 MB bellek kullanımı.
Dosya belleği
Dosya destekli bellek için genel kurallar şunlardır:
- Genel olarak dosya belleği, işletim sistemi bellek yönetimi tarafından iyi bir şekilde yönetilir.
- Şu anda bunun bellek baskısının önemli bir nedeni olmadığını tespit ettik.
Ancak genel olarak dosya belleğiyle çalışırken:
- Derlemenize kullanılmayan kitaplıklar eklemeyin ve mümkün olduğunda kitaplıkların tamamını değil, küçük alt kümelerini kullanın.
- Büyük dosyaları bellekte açık tutma ve işiniz biter bitmez bunları serbest bırakma
- Java ve Kotlin sınıfları için derlenmiş kod boyutunuzu en aza indirin. Uygulamanızı küçültme, karartma ve optimize etme kılavuzunu inceleyin.
Belirli TV önerileri
Bu bölümde, TV cihazlarındaki bellek kullanımını optimize etmek için belirli öneriler sunulmaktadır.
Ekran kartı belleği
Uygun resim biçimlerini 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 resimler 720p kullanıcı arayüzü cihazında 720p'ye düşürülmelidir.
- Mümkün olduğunda donanım destekli bitmap'leri kullanın.
- Glide gibi kitaplıklarda, varsayılan olarak devre dışı olan
Downsampler.ALLOW_HARDWARE_CONFIG
özelliğini etkinleştirin. Bu özelliği etkinleştirmek, aksi takdirde hem grafik belleğinde hem de anonim bellekte yer alacak bitmap'lerin yinelenmesini önler.
- Glide gibi kitaplıklarda, varsayılan olarak devre dışı olan
- Ara oluşturmalardan ve yeniden oluşturmalardan kaçının
- Aşağıdakiler Android GPU Inspector ile tanımlanabilir:
- "Doku" bölümünde, yalnızca öğeleri oluşturan öğeler yerine nihai oluşturma işlemine yönelik adımlar olan resimleri bulun. Bu, genellikle "ara oluşturma" olarak adlandırılır.
- Android SDK uygulamaları için genellikle bu düzenin ara oluşturma işlemlerini devre dışı bırakmak amacıyla düzen işaretini
forceHasOverlappedRendering:false
kullanarak bunları kaldırabilirsiniz. - Çakışan oluşturma işlemleriyle ilgili mükemmel bir kaynak olan Çakışan Oluşturma İşlemlerinden Kaçınma başlıklı makaleyi inceleyin.
- Mümkün olduğunda yer tutucu resim yüklemekten kaçının. Yer tutucu dokular için
@android:color/
veya@color
öğesini kullanın. - Oluşturma işlemi çevrimdışı olarak yapılabiliyorsa cihazda birden fazla görüntüyü birleştirme işlemlerinden kaçının. İndirilen resimlerden resim oluşturmak yerine bağımsız resimler yüklemeyi tercih edin.
- Bit eşlemleriyle daha iyi çalışmak için Bit eşlemleri işleme kılavuzunu inceleyin.
Anonim+takas belleği
Anon+Swap, Android Studio bellek profilleyicisinde Native + Java + Stack tahsislerinden oluşur. Cihazın bellek sınırlamasına sahip olup olmadığını kontrol etmek için ActivityManager.isLowMemoryDevice()
simgesini kullanın ve bu kurallara uyarak bu duruma uyum sağlayı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 için geçerlidir:
- 1 GB / 1080p için 40-60 MB
- 1,5 GB / 1080p için 60-80 MB
- 1,5 GB / 2160p için 80-100 MB
- 2 GB / 2160p için 100-120 MB
- Anonim belleğin toplam miktarında artış olmasını önlemek için bölüm değiştirilirken 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()
oluştuğunda oynatma işlemini durdurun, yaptığınız tüm çalışmaları kaydedin ve kaynaklarınızı serbest bırakılacak şekilde ayarlayın. Daha sonra ihtiyaç duyabileceğiniz işleri planlamak için. İşler ve Alarmlar bölümüne bakın.- Etkinlik yaşam döngüsü çağrılarıyla başa çıkmanıza yardımcı olması için
LiveData
veLifecycleOwner
gibi yaşam döngüsü bilinçli bileşenleri kullanabilirsiniz. - Çalışmanızı yaşam döngüsü bilincine sahip hale getirmek için Kotlin eş yordamlarını ve Kotlin akışlarını da kullanabilirsiniz.
- Etkinlik yaşam döngüsü çağrılarıyla başa çıkmanıza yardımcı olması için
- Video ararken arabelleğin belleğine dikkat edin: Geliştiriciler, kullanıcı için videoyu hazır tutmak amacıyla genellikle gelecekteki içerik için 15-60 saniye daha ayarlar. Ancak bu, ek bellek yükü oluşturur.
Genel olarak, kullanıcı yeni video konumunu seçene kadar 5 saniyeden fazla önbelleğe alma işlemi yapmayın. İleri sararken kesinlikle daha fazla ön arabelleğe alma işlemi yapmanız gerekiyorsa şunları yapmayı unutmayın:
- 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).
- 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 için geçerlidir:
- Ayrımlar:
- Anonymous bellekte resimleri kopyalamamak için grafik belleği kılavuzunu kullanın.
- Görüntüler genellikle en fazla bellek kullanan öğelerdir. Bu nedenle, kopyalarının oluşturulması cihaza çok fazla baskı uygulayabilir. Bu durum özellikle resim ızgara 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şlemelere ve nesnelere ait referansların bırakılmadığından emin olun.
- Anonymous bellekte resimleri kopyalamamak için grafik belleği kılavuzunu kullanın.
- Kitaplıklar:
- Yeni kitaplıklar eklerken kitaplıklardan bellek ayırma işlemlerini profilleyin. Yeni kitaplıklar, ek kitaplıklar da yükleyebilir. Bu da ayırma işlemi yapabilir ve bağlantılar oluşturabilir.
- Ağ iletişimi:
- Uygulama başlatılırken engelleme ağı çağrıları yapmayın. Bu çağrılar, uygulamanın başlatılma süresini yavaşlatır ve özellikle uygulama yüküyle sınırlı olan bellekte başlatma sırasında ek bellek yükü oluşturur. Önce bir yükleme veya açılış ekranı gösterin ve kullanıcı arayüzü oluşturulduktan sonra ağ isteklerini gönderin.
Bağlamalar
Bağlantılar, API çağrısını kolaylaştırmak için diğer uygulamaları belleğe getirdiği veya bağlantılı uygulamanın bellek tüketimini artırdığı (zaten bellekteyse) için ek bellek yükü oluşturur. Bu da ön plan uygulaması için kullanılabilir hafızayı azaltır. Bir hizmeti bağlarken bağlamayı ne zaman ve ne kadar süreyle kullandığınıza dikkat edin. Gerekmediği anda bağlantıyı kaldırdığı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 oynatmadan önce cihaz bütünlüğünü kontrol etme
- İçerik oynatmadan önce PlayIntegrity
StandardIntegrityManager
referanslarını yayınlayın.
- Play Faturalandırma Kitaplığı: Google Play'i kullanarak abonelikleri ve satın alma işlemlerini yönetmek için kullanılır
- Yükleme ekranından sonra kitaplığı başlatın ve herhangi bir medya oynatmadan önce tüm faturalandırma işlemlerini tamamlayın.
- Kitaplığı kullanmayı bitirdiğinizde ve her zaman video veya medya oynatmadan önce
BillingClient.endConnection()
simgesini kullanın. - Faturalandırma işleminin tekrar yapılması gerekmesi ihtimaline karşı hizmetin bağlantısının kesilip kesilmediğini kontrol etmek için
BillingClient.isReady()
veBillingClient.getConnectionState()
seçeneklerini kullanın. Ardından, işlemi tamamladıktan sonraBillingClient.endConnection()
seçeneğini tekrar uygulayın.
- GMS FontsProvider
- Yazı tiplerinin indirilmesi maliyetli olduğundan ve FontsProvider bunu yapmak için hizmetleri bağladığından, RAM'i düşük cihazlarda yazı tipi sağlayıcı 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 metin okuma özelliğini veya androidx.leanback kitaplığını kullanın.
- Arama özelliğini uygulamak için Arama yönergelerini uygulayın.
- Not: leanback desteği sonlandırıldı ve uygulamaların TV Compose'a taşınması gerekir.
- Oluşturma uygulamaları için:
- Sesli aramayı uygulamak için Gboard metin okuma özelliğini kullanın.
- Uygulamanızdaki medya içeriklerinin keşfedilebilir olmasını sağlamak için Sonrakini İzle özelliğini uygulayın.
- Leanback uygulamaları için: Gboard metin okuma özelliğini veya androidx.leanback kitaplığını kullanın.
Ön Plan Hizmetleri
Ön plan hizmetleri, bir bildirime bağlı olan özel bir hizmet türüdür. Bu bildirim, telefon ve tabletlerdeki bildirim tepsisinde gösterilir ancak TV cihazlarında bu cihazlarla aynı anlamda bir bildirim tepsisi yoktur. Ön plan hizmetleri, uygulama arka plandayken çalışmaya devam edebildikleri için yararlı olsalar da TV uygulamaları aşağıdaki yönergelere uymalıdır:
Android TV ve Google TV'de, kullanıcı uygulamadan ayrıldıktan sonra ön plan hizmetlerinin yalnızca aşağıdaki durumlarda çalışmaya devam etmesine izin verilir:
- Ses uygulamaları için: Ön plan hizmetlerinin yalnızca kullanıcı uygulamadan ayrıldıktan sonra ses parçasını çalmaya devam etmek için çalışmaya devam etmesine izin verilir. Ses oynatma sona erdikten hemen sonra hizmet durdurulmalıdır.
- Diğer uygulamalar için: Tüm ön plan hizmetleri, kullanıcı uygulamanızdan ayrıldıktan sonra durdurulmalıdır. Uygulamanın hâlâ çalıştığı ve kaynak tükettiği konusunda kullanıcıyı bilgilendirecek bir bildirim olmadığından bu işlem gereklidir.
- Önerileri güncelleme veya Sonrakini İzle gibi arka plan işlerinde
WorkManager
değerini kullanın.
İşler ve Alarmlar
WorkManager
, arka planda yinelenen işleri planlamak için en gelişmiş Android API'sidir.
WorkManager, mevcut olduğunda yeni JobScheduler
değerini, mevcut olmadığında ise eski AlarmManager
değerini kullanır. TV'de planlanmış işleri gerçekleştirmeyle ilgili en iyi uygulamalar için aşağıdaki önerileri uygulayın:
- SDK 23 ve sonraki sürümlerde, özellikle
AlarmManager.set()
,AlarmManager.setExact()
ve benzer yöntemlerin, sistemin işlerin çalıştırılacağı uygun zamana (ör. cihaz boştayken) karar vermesine izin vermemesi nedeniyleAlarmManager
API'lerini kullanmaktan kaçının. - RAM'i düşük 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, uygun olduğunda işlerinizi ç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()
- Düzenli olarak iş çalıştırmanız gerekiyorsa (örneğin, kullanıcının başka bir cihazdaki uygulamanızdaki içerik izleme etkinliğine göre Sonrakini İzle'yi 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ştirmeyle ilgili genel bilgiler sağlar:
- Nesne tahsislerini en aza indirin, nesnelerin yeniden kullanımını optimize edin ve kullanılmayan nesnelerin tahsisini hemen kaldırın.
- Nesnelere (özellikle bitmap'lere) ait referansları bekletmeyin.
- Sistem bellek işleme sürecini etkilediği için
System.gc()
ve doğrudan bellek bırakma çağrılarını kullanmaktan kaçının: Örneğin, zRAM kullanan cihazlardagc()
için zorunlu bir çağrı, belleğin sıkıştırılması ve sıkıştırmanın kaldırılması nedeniyle bellek kullanımını geçici olarak artırabilir. - Liste öğelerini yeniden oluşturmak yerine yeniden kullanmak için
LazyList
'i kullanın. Bu öğe, Oluştur'daki katalog tarayıcısında veya artık desteği sonlandırılmış Leanback kullanıcı arayüzü araç setinde gösterildiği gibidir.RecyclerView
- 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 ayırmayı önleyen güncelleme aralıkları tanımlayın.
- Olası bellek sızıntılarını kontrol edin.
- Anonim mesaj dizileri içindeki referanslar, hiçbir zaman serbest bırakılmayan video arabelleklerinin yeniden atanması ve benzer durumlar gibi tipik bellek sızıntısı durumlarına dikkat edin.
- Bellek sızıntılarını ayıklamak için yığın dökümü kullanın.
- Uygulamanızı sıfırdan başlatırken gereken tam zamanında derleme miktarını en aza indirmek için temel profiller oluşturun.
Doğrudan bellek geri alma işlemini 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 alma özelliğini kullanması gerekebilir.
Bu işlem, boşaltılan bellek sayfalarını beklemek için ayrıştırıcı iş parçacıklarını tamamen duraklatmayı içerir. Bu durum, arka planda bellek geri kazanma işlemi proaktif olarak yeterli bellek havuzu sağlayamadığı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 duraklamalar veya takılmalara neden olabilir. Bu bağlamda, iş parçacıkları ayırma işlemi malloc()
gibi uygulama kodu çağrılarıyla sınırlı değildir. Örneğin, kod sayfalarında sayfaya bellek ayrılması gerekir.
Araçlar özeti
- Kullanım sırasındaki bellek tüketiminizi kontrol etmek için Android Studio bellek profili oluşturma aracını kullanın.
- Belirli nesne ve bitmap tahsislerini kontrol etmek için heapdump'ı kullanın.
- Java veya Kotlin olmayan atamaların kontrol edilmesi için yerel bellek profilleyiciyi kullanın.
- Grafik tahsislerini kontrol etmek için Android GPU Inspector'ı kullanın.