Bu sayfada, uygulamanızdaki bellek kullanımını proaktif olarak nasıl azaltacağınız açıklanmaktadır. Android işletim sisteminin belleği nasıl yönettiği hakkında bilgi edinmek için Bellek yönetimine genel bakış başlıklı makaleyi inceleyin.
Rastgele erişimli bellek (RAM), herhangi bir yazılım geliştirme ortamı için değerli bir kaynaktır ve fiziksel belleğin genellikle sınırlı olduğu mobil işletim sistemleri için daha da değerlidir. Android Runtime (ART) ve Dalvik sanal makinesi rutin çöp toplama işlemi gerçekleştirse de bu, uygulamanızın belleği ne zaman ve nerede ayırıp serbest bıraktığını göz ardı edebileceğiniz anlamına gelmez. Yine de genellikle statik üye değişkenlerinde nesne referanslarını tutmaktan kaynaklanan bellek sızıntılarını önlemeniz ve yaşam döngüsü geri çağırmaları tarafından tanımlanan uygun zamanda Reference nesnelerini serbest bırakmanız gerekir.
Uygulamanızın kod ve kaynak ayak izini azaltma
Kodunuzdaki bazı kaynaklar ve kitaplıklar, farkında olmadan bellek tüketebilir. Üçüncü taraf kitaplıkları veya yerleştirilmiş kaynaklar da dahil olmak üzere uygulamanızın genel boyutu, uygulamanızın ne kadar bellek tükettiğini etkileyebilir. Kodunuzdaki gereksiz, lüzumsuz veya şişirilmiş bileşenleri, kaynakları ve kitaplıkları kaldırarak uygulamanızın bellek tüketimini iyileştirebilirsiniz.
R8'i etkinleştirerek uygulamanın genel boyutunu küçültme
Derlenmiş uygulama kodunuz, çalışma zamanı belleğinizin etkin bir parçasıdır. Her sınıf, yöntem, kitaplık bağımlılığı ve dize sabiti çalıştırıldığında RAM'e yüklenmelidir. Derlenmiş kod tabanınız ne kadar büyükse uygulamanızın var olması için o kadar fazla fiziksel RAM gerekir.
Uygulamanızın bellekte kaplanan yerini azaltmak için R8'i kullanabilirsiniz. R8 geleneksel olarak APK boyutunu küçültmesiyle bilinse de çalışma zamanı belleği (RAM) üzerinde doğrudan ve olumlu bir etkisi vardır. R8, ölü kodu temizlemek, gereksiz sınıfları birleştirmek, yöntemleri satır içi hale getirmek ve tanımlayıcıları küçültmek için uygulamanızın bayt kodunu analiz eder. APK'dan RAM'e daha az derlenmiş bayt kodu yükleyerek uygulamanın genel temel bellekte kaplanan yerini azaltır. Ayrıca, sınıf, yöntem ve alan adlarını daha kısa tanımlayıcılar hâline getirerek RAM yükünü doğrudan azaltır. Sınıf birleştirme ve kapsamlı yöntem satır içi hâle getirme gibi optimizasyonlar da maliyetli çalışma zamanı aramalarını ve ayırma kalıplarını değiştirerek yığın ve yığın belleğin optimize edilmesini sağlar.
Saklama kurallarını anlama
Koruma kuralları, R8'e optimizasyon sırasında kodunuzun hangi bölümlerinin korunacağını söyleyen yapılandırma talimatlarıdır. Bu kurallar, R8'in uygulamanızın kullandığı kodu kaldırmasını veya küçültmesini önler. Daha fazla bilgi için Keep kurallarına genel bakış başlıklı makaleyi inceleyin.
Kötü yazılmış koruma kuralları, R8'in kod tabanınızın büyük bölümlerini optimize etmesini engeller. Çok geniş kapsamlı saklama kurallarından kaçının ve şu en iyi uygulamaları izleyin:
- Kaçınılması gereken genel kurallar:
-dontoptimize: Uygulamanın tamamında optimizasyonu tamamen devre dışı bırakır. Bu da daha büyük ve daha yavaş çalıştırılabilir dosyalarla sonuçlanır.-dontshrink: Kullanılmayan kod ve kaynakların kaldırılmasını önler.-dontobfuscate: Ad küçültmeyi önler ve değerli bellek tasarruflarını (özellikle büyük uygulamalarda) kaçırır.
Paket genelinde joker karakterlerden kaçının:
-keep class com.example.package.** { *; }gibi geniş kapsamlı kurallar, R8'in söz konusu paketteki her sınıfı, alanı ve yöntemi korumasına neden olur. Bu, R8'in söz konusu paketteki kodu kaldırma, optimize etme veya küçültme özelliğini tamamen durdurur.Varsayılan R8 yapılandırma dosyasını kullanın: Her zaman
proguard-android-optimize.txtkullanın.
Saklama kuralları yazma hakkında daha fazla bilgi için Saklama kurallarına genel bakış başlıklı makaleyi inceleyin. Kullanılacak ve kaçınılacak belirli kalıplar için Keep kurallarıyla ilgili en iyi uygulamalar başlıklı makaleyi inceleyin.
R8 Yapılandırma Analiz Aracı, R8 yapılandırmanız ve her saklama kuralının uygulamanızı nasıl etkilediği hakkında analizler sağlar. Optimizasyonu engelleyen kuralları belirleme hakkında daha fazla bilgi için R8 Yapılandırma Analiz Aracı başlıklı makaleyi inceleyin.
Harici kitaplıkları kullanma konusunda dikkatli olun
Harici kitaplık kodu genellikle mobil ortamlar için yazılmaz ve mobil istemcide çalışmak için verimsiz olabilir. Harici bir kitaplık kullandığınızda bu kitaplığı mobil cihazlar için optimize etmeniz gerekebilir. Bu çalışmayı önceden planlayın ve kullanmadan önce kitaplığı kod boyutu ve RAM ayak izi açısından analiz edin.
Mobil cihazlar için optimize edilmiş bazı kitaplıklar bile farklı uygulamalar nedeniyle sorunlara neden olabilir. Örneğin, bir kitaplık lite protobuf'ları kullanırken diğeri micro protobuf'ları kullanabilir. Bu durumda uygulamanızda iki farklı protobuf uygulaması olur. Bu durum, günlük kaydı, analiz, resim yükleme çerçeveleri, önbelleğe alma ve beklemediğiniz birçok şeyin farklı uygulamalarında yaşanabilir.
Uygulamanızı R8 kullanarak optimize etmek, bağımlılıklardaki kullanılmayan kodu kaldırabilir ancak bu optimizasyonun etkinliği genellikle kitaplığın dahili yapılandırmasıyla sınırlıdır. Örneğin, geniş kapsamlı koruma kuralları veya bir kitaplıkta yansıtma kullanılması, R8'in kodunu küçültmesini engelleyerek daha büyük bir bellek alanı oluşturabilir. Verimli kitaplıklar seçmeyle ilgili stratejiler için Kitaplıkları akıllıca seçin başlıklı makaleyi inceleyin.
Düzinelerce özellikten yalnızca bir veya ikisi için paylaşılan kitaplık kullanmaktan kaçının. Kullanmadığınız çok miktarda kodu ve ek yükü dahil etmeyin. Kitaplık kullanıp kullanmayacağınıza karar verirken ihtiyacınıza en uygun uygulamayı arayın. Aksi takdirde, kendi uygulamanızı oluşturmayı tercih edebilirsiniz.
Bağımlılık ekleme için Hilt veya Dagger 2 kullanma
Bağımlılık ekleme çerçeveleri, yazdığınız kodu basitleştirebilir ve test ile diğer yapılandırma değişiklikleri için yararlı olan uyarlanabilir bir ortam sağlayabilir.
Uygulamanızda bağımlılık ekleme çerçevesi kullanmayı planlıyorsanız Hilt veya Dagger'ı kullanmayı düşünebilirsiniz. Hilt, Dagger üzerinde çalışan Android için bir bağımlılık ekleme kitaplığıdır. Dagger, uygulamanızın kodunu taramak için yansıtma kullanmaz. Android uygulamalarında Dagger'ın statik derleme zamanı uygulamasını gereksiz çalışma zamanı maliyeti veya bellek kullanımı olmadan kullanabilirsiniz.
Yansıtma kullanan diğer bağımlılık ekleme çerçeveleri, kodunuzu ek açıklamalar için tarayarak işlemleri başlatır. Bu işlem, önemli ölçüde daha fazla CPU döngüsü ve RAM gerektirebilir ve uygulama başlatıldığında belirgin bir gecikmeye neden olabilir.
Bağımlılık yerleştirme kullanırken nesnelerin kapsamının uygun şekilde belirlendiğinden emin olarak bellek sızıntılarını önlemeye dikkat edin. Nesneleri yanlış yaşam döngüsüne bağlayarak gereğinden uzun süre saklamak bellek sızıntılarına yol açabilir.
Resim yükleme konusunda bilinçli olun
Grafik bit eşlemler genellikle uygulamanızın belleğinde bulunan en büyük ortak nesnelerdir. JPEG gibi sıkıştırılmış dosyalarla çalışıyor olsanız bile, dosyanın ekranda gösterilmesi için sıkıştırılmamış bir bit eşleme haline getirilmesi gerekir. Küçük bir sıkıştırılmış resim dosyası çok büyük bir bit eşleme olarak genişleyebilir.
Örneğin, çoğu bit eşlem ARGB_8888 yapılandırmasını kullanır. Bu yapılandırmada her piksel için 4 baytlık bellek gerekir. Kırmızı, yeşil, mavi ve alfa (şeffaflık) için birer bayt ayrılır. 100 KB boyutunda bir JPEG'iniz varsa ve bunu 1.000x1.000 piksellik bir görünümde gösteriyorsanız bit eşlem, 1.000.000 pikselin her biri için 4 bayt gerektirir ve toplamda 4 MB bellek kullanır.
Resim kullanımınızı optimize etmek için yapabileceğiniz birkaç şey vardır. Örneğin, resim yükleme kitaplıklarını kullanmak, ihtiyaç duyulmadığında belleği serbest bırakmanıza yardımcı olabilir. Görüntüleri verimli bir şekilde işleme hakkında bilgi edinmek için Bitmap görüntüleri optimize etme başlıklı makaleyi inceleyin.
Kullanılabilir belleği ve bellek kullanımını izleme
Uygulamanızın bellek kullanımıyla ilgili sorunları düzeltebilmek için önce bu sorunları bulmanız gerekir. Android Studio bellek profil aracı, bellek sorunlarını aşağıdaki şekillerde bulup teşhis etmenize yardımcı olur:
- Uygulamanızın zaman içinde belleği nasıl tahsis ettiğini görün. Bellek profil oluşturucu, uygulamanızın kullandığı bellek miktarı, ayrılan Java nesnelerinin sayısı ve atık toplama işleminin ne zaman gerçekleştiğiyle ilgili gerçek zamanlı bir grafik gösterir.
- Atık toplama etkinliklerini başlatın ve uygulamanız çalışırken Java yığınının anlık görüntüsünü alın.
- Uygulamanızın bellek ayırmalarını kaydedin, ayrılan tüm nesneleri inceleyin, her ayırma için yığın izlemeyi görüntüleyin ve Android Studio düzenleyicisinde ilgili koda gidin.
Bellek profil oluşturucu, LeakCanary bellek sızıntısı tespit kitaplığıyla da entegre olur. LeakCanary'yi kullanarak bellek sızıntısı analizini test cihazından geliştirme makinenize taşıyabilir ve iş akışınızı önemli ölçüde hızlandırabilirsiniz. Daha fazla bilgi için Android Studio sürüm notlarına bakın.
Üretim uygulamanızı çalıştıran kullanıcıların verilerine göre bellek sorunlarını teşhis etmek için kullanabileceğiniz başka araçlar da vardır:
- Düşük bellek nedeniyle işlem sonlandırma (LMK) etkinliklerini izlemek için Android Vitals'ı kullanın.
- Bellek yetersizliği hatalarının yanı sıra bellek sızıntılarından kaynaklanabilecek anormal uygulama davranışlarını izlemek için Profiling Manager'ı kullanın.
Olaylara göre belleği serbest bırakma
Android, Bellek yönetimine genel bakış bölümünde açıklandığı gibi, kritik görevler için bellek boşaltmak gerektiğinde uygulamanızdan bellek geri alabilir veya uygulamanızı tamamen durdurabilir. Sistem belleğini daha iyi dengelemek ve sistemin uygulama sürecinizi durdurmasını önlemek için ComponentCallbacks2 arayüzünü Activity sınıflarınızda uygulayabilirsiniz. Sağlanan onTrimMemory()
geri çağırma yöntemi, uygulamanızı yaşam döngüsü veya bellekle ilgili etkinlikler konusunda bilgilendirir. Bu etkinlikler, uygulamanızın bellek kullanımını gönüllü olarak azaltması için iyi bir fırsat sunar.
Belleği boşaltmak, uygulamanızın düşük bellek katili tarafından sonlandırılma sıklığını azaltabilir.
onTrimMemory() uygulamanız yalnızca TRIM_MEMORY_UI_HIDDEN ve TRIM_MEMORY_BACKGROUND etkinliklerine odaklanmalıdır. (Android 14'ten itibaren sistem, diğer eski sabitler için bildirim göndermez. Bu sabitler, Android 15'te resmen kullanımdan kaldırıldı.)
TRIM_MEMORY_UI_HIDDEN: Bu sinyal, uygulamanızın kullanıcı arayüzünün kullanıcının görünümünden çıktığını gösterir. Bu geçiş, bit eşlemler, video oynatma arabellekleri veya karmaşık animasyon kaynakları gibi kesinlikle kullanıcı arayüzüne bağlı olan önemli bellek ayırmalarını serbest bırakma fırsatı sunar.TRIM_MEMORY_BACKGROUND: Bu sinyal, işleminizin arka planda çalıştığını ve sistemin genel bellek ihtiyaçlarını karşılamak için sonlandırılmaya aday olduğunu gösterir. İşleminizin önbelleğe alınmış durumda kalma süresini uzatmak ve uygulamanın soğuk başlatma sayısını azaltmak için, kullanıcı oturumuna devam ettiğinde kolayca yeniden oluşturulabilecek tüm kaynakları agresif bir şekilde serbest bırakmanız gerekir.
Bu kod örneğinde, farklı bellekle ilgili etkinliklere yanıt vermek için onTrimMemory() geri çağırma işlevinin nasıl uygulanacağı gösterilmektedir:
Kotlin
import android.content.ComponentCallbacks2
// Other import statements.
class MainActivity : AppCompatActivity(), ComponentCallbacks2 {
// Other activity code.
/**
* Release memory when the UI becomes hidden or when system resources become low.
* @param level the memory-related event that is raised.
*/
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
import android.content.ComponentCallbacks2;
// Other import statements.
public class MainActivity extends AppCompatActivity
implements ComponentCallbacks2 {
// Other activity code.
/**
* Release memory when the UI becomes hidden or when system resources become low.
* @param level the memory-related event that is raised.
*/
public void onTrimMemory(int 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.
}
}
}
Ne kadar belleğe ihtiyacınız olduğunu kontrol etme
Android, birden fazla işlemin çalışmasına izin vermek için her uygulamaya ayrılan yığın boyutu için kesin bir sınır belirler. Yığın boyutu sınırı, cihazın genel olarak ne kadar RAM'e sahip olduğuna bağlı olarak cihazlar arasında değişiklik gösterir. Uygulamanız yığın kapasitesine ulaşıp daha fazla bellek ayırmaya çalışırsa sistem OutOfMemoryError oluşturur.
Belleğin tükenmesini önlemek için sistemi sorgulayarak mevcut cihazda ne kadar yığın alanı olduğunu belirleyebilirsiniz. getMemoryInfo() işlevini çağırarak bu rakam için sistemi sorgulayabilirsiniz. Bu, kullanılabilir bellek, toplam bellek ve sistemin işlemleri durdurmaya başladığı bellek düzeyi olan bellek eşiği dahil olmak üzere cihazın mevcut bellek durumu hakkında bilgi sağlayan bir ActivityManager.MemoryInfo nesnesi döndürür. ActivityManager.MemoryInfo nesnesi, cihazın belleğinin azalıp azalmadığını belirten basit bir Boole değeri olan lowMemory değerini de gösterir.
Aşağıdaki örnek kod snippet'inde, uygulamanızda getMemoryInfo() yönteminin nasıl kullanılacağı gösterilmektedir.
Kotlin
fun doSomethingMemoryIntensive() {
// Before doing something that requires a lot of memory,
// check whether the device is in a low memory state.
if (!getAvailableMemory().lowMemory) {
// Do memory intensive work.
}
}
// Get a MemoryInfo object for the device's current memory status.
private fun getAvailableMemory(): ActivityManager.MemoryInfo {
val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
return ActivityManager.MemoryInfo().also { memoryInfo ->
activityManager.getMemoryInfo(memoryInfo)
}
}
Java
public void doSomethingMemoryIntensive() {
// Before doing something that requires a lot of memory,
// check whether the device is in a low memory state.
ActivityManager.MemoryInfo memoryInfo = getAvailableMemory();
if (!memoryInfo.lowMemory) {
// Do memory intensive work.
}
}
// Get a MemoryInfo object for the device's current memory status.
private ActivityManager.MemoryInfo getAvailableMemory() {
ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
return memoryInfo;
}
Düşük bellek nedeniyle sonlandırılan işlemleri izleme
Kullanıcıların görebileceği düşük bellek nedeniyle işlem sonlandırmalar (LMK), sistem belleği kritik düzeyde azaldığında gerçekleşir. Bellek azaldığında lmkd (düşük bellek durumunda işlem sonlandırma arka plan programı), işlemleri oom_adj_score değerlerine göre sonlandırır. Önbelleğe alınan veya ilişkili kullanıcı arayüzü olmayan bir hizmet (ör. iş) çalıştıran uygulamalar en yüksek puanlara sahiptir ve ilk olarak sonlandırılır. Bellek kritik düzeyde düşük kalırsa daemon, oom_adj_score değeri 0 olan işlemlerden bellek geri almaya zorlanır.
Bu puan görünür uygulamalar için ayrıldığından, bu uygulamaların sonlandırılması hemen gerçekleşir ve sorunsuz bir şekilde çıkış yapılmaz. Son kullanıcıya göre uygulama çökmüş gibi görünür. Bu durum genellikle standart yaşam döngüsü durumu kaydetme mekanizmalarını atlayarak kullanıcının ilerlemesinin kaybolmasına neden olur.
Ön plan işlemlerinin sonlandırılması, bellek yönetimindeki hataların yüksek doğruluklu bir göstergesi olduğundan Android Vitals'da öncelikli olarak ele alınır. %1'ten yüksek olan tüm LMK oranları, acil müdahale gerektiren kritik bir durumu gösterirken düşük bir oran mutlaka sağlıklı bir durumu ifade etmez. Kullanıcı tarafından algılanan düşük LMK oranı, LMK daemon'unun işlemleri arka planda çalışırken sık sık sonlandırdığı anlamına gelebilir. Bu durum, "sıcak başlatma" performansını ve çoklu görev akıcılığını düşürür. Bu nedenle, uzun vadeli kararlılık ve cihaz sağlığı için mevcut LMK puanınızdan bağımsız olarak bellekle ilgili en iyi uygulamalara uymanızı öneririz.
Bellek sorunlarını izlemek için ProfilingManager öğesini kullanma
Android platformu,ProfilingManager adlı bir gelişmiş gözlemlenebilirlik API'si sunar. Bu API, üretimde kullanıcı verilerini ayarladığınız tetikleyicilere göre yakalamanıza olanak tanır. Bu sayede, yeniden üretilmesi zor olan bellek sorunlarını belirleyebilirsiniz.
Android 17 ile kullanıma sunulan iki yeni tetikleyici, özellikle bellek sorunlarını tespit etmek için yararlıdır:
TRIGGER_TYPE_OOMuygulamanınOutOfMemoryErroroluşturduğunu gösterir. Bu, uygulama kilitlendikten sonraki başlatma işleminde, uygulama profil oluşturma tetikleyicileri için kaydolduğunda tetiklenir.TRIGGER_TYPE_ANOMALYSistem, uygulamada anormal davranış algıladığında tetiklenir. Diğer şeylerin yanı sıra, bu durum aşırı bellek kullanımıyla tetiklenebilir. Uygulama aşırı bellek kullanımı gösterdikten ve sistem, sorunlu işlemi durdurmak için herhangi bir işlem yapmadan önce tetiklenir. Örneğin, uygulama Android 17'de kullanıma sunulan bellek sınırlarını aşarsa sistem uygulamayı kapatmadanTRIGGER_TYPE_ANOMALYtetiklenir.
ProfilingManager kullanarak tetikleyicileri programatik olarak kaydetme ve alma hakkında daha fazla bilgi için tetikleyici tabanlı profilleme belgelerine bakın.
Ayrıca, izleme başlangıç ve bitiş noktalarını manuel olarak tanımlamak için uygulama odaklı profillemeyi de kullanabilirsiniz. Bellek sızıntısı veya aşırı bellek kullanımı olabileceğinden şüphelendiğiniz alanlarda yığın dökümlerini veya yığın profillerini manuel olarak yakalamak için bu yöntemi kullanmanızı öneririz.
Daha az bellek kullanan kod yapıları kullanma
Bazı Android özellikleri, Java sınıfları ve kod yapıları diğerlerinden daha fazla bellek kullanır. Kodunuzda daha verimli alternatifler seçerek uygulamanızın kullandığı bellek miktarını en aza indirebilirsiniz.
Hizmetleri dikkatli kullanın
Gereksiz olduğunda hizmetleri çalıştırmamaya özen göstermenizi önemle tavsiye ederiz. Gereksiz hizmetlerin çalışır durumda bırakılması, bir Android uygulamasının yapabileceği en kötü bellek yönetimi hatalarından biridir. Uygulamanızın arka planda çalışması için bir hizmete ihtiyacı varsa bir iş çalıştırması gerekmediği sürece hizmeti çalıştırmaya devam etmeyin. Hizmetinizin görevini tamamladığında durdurulmasını sağlayın. Aksi takdirde bellek sızıntısına neden olabilirsiniz.
Bir hizmeti başlattığınızda sistem, bu hizmetin sürecini çalıştırmaya devam etmeyi tercih eder. Bu davranış, bir hizmet tarafından kullanılan RAM diğer işlemler için kullanılamadığından hizmet süreçlerini çok maliyetli hale getirir. Bu, sistemin LRU önbelleğinde tutabileceği önbelleğe alınmış işlem sayısını azaltarak uygulama geçişini daha az verimli hale getirir. Hatta bellek azaldığında ve sistem, şu anda çalışan tüm hizmetleri barındıracak kadar işlem sürdüremediğinde sistemde thrashing'e yol açabilir.
Genel olarak, kullanılabilir belleğe sürekli olarak yük bindirdikleri için kalıcı hizmetleri kullanmaktan kaçının. Bunun yerine WorkManager gibi alternatif bir uygulama kullanmanızı öneririz.WorkManager'ı kullanarak arka plan işlemlerini nasıl planlayacağınız hakkında daha fazla bilgi için Kalıcı çalışma başlıklı makaleyi inceleyin.
Optimize edilmiş veri kapsayıcıları kullanma
Programlama dili tarafından sağlanan sınıfların bazıları mobil cihazlarda kullanılmak üzere optimize edilmemiştir. Örneğin, genel HashMap uygulaması, her eşleme için ayrı bir giriş nesnesi gerektirdiğinden bellek açısından verimsiz olabilir.
Android çerçevesi, SparseArray, SparseBooleanArray ve LongSparseArray gibi çeşitli optimize edilmiş veri kapsayıcıları içerir. Örneğin, SparseArray sınıfları daha verimlidir. Çünkü sistemin anahtarı ve bazen de değeri otomatik olarak kutulamasına gerek kalmaz. Bu da her giriş için bir veya iki nesne daha oluşturur.
Gerekirse yalın bir veri yapısı için her zaman ham dizilere geçebilirsiniz.
Kod soyutlamalarıyla ilgili dikkatli olun
Geliştiriciler, kod esnekliğini ve bakımını iyileştirebildiği için genellikle iyi bir programlama uygulaması olarak soyutlamaları kullanır. Ancak soyutlamalar genellikle daha fazla kodun yürütülmesini gerektirir. Uygulamanızın kod ve kaynak ayak izini küçültme başlıklı makalede ayrıntılı olarak açıklandığı gibi, derlenmiş kod tabanının büyük olması uygulamanızın gerektirdiği fiziksel RAM'i doğrudan artırır. Soyutlamalarınız önemli ölçüde faydalı değilse bunları kullanmayın.
Serileştirilmiş veriler için lite protobuf'ları kullanma
Protokol arabellekleri (protobuf), Google tarafından yapılandırılmış verileri serileştirmek için tasarlanmış, dilden ve platformdan bağımsız, genişletilebilir bir mekanizmadır. XML'e benzer ancak daha küçük, daha hızlı ve daha basittir. Verileriniz için protobuf'ları kullanıyorsanız istemci tarafı kodunuzda her zaman lite protobuf'ları kullanın. Normal protobuf'lar, son derece ayrıntılı kod oluşturur. Bu da uygulamanızın RAM'deki kod yerleşimini artırır (Uygulamanızın kod yerleşimini yönetme ve optimize etme başlıklı makaleye bakın) ve APK boyutunun artmasına neden olur.
Daha fazla bilgi için protobuf readme dosyasına bakın.
Bellek sızıntılarına karşı dikkatli olun
Uygunsuz referans yönetimi, nesnelerin yararlı ömürlerinden daha uzun süre yaşadığı bellek sızıntılarına yol açabilir. Bu durum, çöp toplayıcının sızan nesnenin belleğini geri kazanmasını engeller. Bellek sızıntılarını önlemek için yaşam döngüsüne duyarlı tasarım uygulayın.
Bellek karmaşıklığından kaçının
Çöp toplama etkinlikleri, uygulamanızın performansını etkilemez. Ancak kısa bir süre içinde gerçekleşen çok sayıda çöp toplama etkinliği, çöp toplayıcı ile uygulama iş parçacıkları arasındaki gerekli etkileşimler nedeniyle karelerin ayarlanma süresini biraz artırmanın yanı sıra pili de hızlı bir şekilde boşaltabilir. Sistem, çöp toplama işlemine ne kadar çok zaman harcarsa pil o kadar hızlı boşalır.
Bellek karmaşıklığı genellikle çok sayıda atık toplama etkinliğinin gerçekleşmesine neden olabilir. Pratikte bellek karmaşıklığı, belirli bir süre içinde ayrılan geçici nesnelerin sayısını ifade eder.
Örneğin, bir for döngüsünde birden fazla geçici nesne ayırabilirsiniz.
Alternatif olarak, bir görünümün onDraw() işlevi içinde yeni Paint veya Bitmap nesneleri oluşturabilirsiniz. Her iki durumda da uygulama, yüksek hacimde hızlı bir şekilde çok sayıda nesne oluşturur. Bu tür nesneler, genç nesildeki tüm kullanılabilir belleği hızlıca tüketerek atık toplama etkinliğinin gerçekleşmesine neden olabilir.
Düzeltmeden önce kodunuzda bellek karmaşıklığının yüksek olduğu yerleri bulmak için Memory Profiler'ı kullanın.
Kodunuzdaki sorunlu alanları belirledikten sonra, performansı etkileyen kritik alanlardaki ayırma sayısını azaltmaya çalışın. Öğeleri iç döngülerden veya fabrika tabanlı ayırma yapısına taşıyabilirsiniz.
Nesne havuzlarının kullanım alanına fayda sağlayıp sağlamadığını da değerlendirebilirsiniz. Nesne havuzunda, nesne örneğini yere bırakmak yerine artık ihtiyaç duyulmadığında havuza bırakırsınız. Bu türden bir nesne örneğine bir sonraki ihtiyaç duyulduğunda, onu ayırmak yerine havuzdan alabilirsiniz.
Bir nesne havuzunun belirli bir durumda uygun olup olmadığını belirlemek için performansı ayrıntılı olarak değerlendirin. Nesne havuzlarının performansı kötüleştirebileceği durumlar vardır. Havuzlar tahsisleri önlese de başka ek yükler getirir. Örneğin, havuzun bakımı genellikle senkronizasyon gerektirir ve bu da göz ardı edilemeyecek bir ek yüke neden olur. Ayrıca, serbest bırakma sırasında bellek sızıntılarını önlemek için havuzdaki nesne örneğinin temizlenmesi ve ardından edinme sırasında başlatılması sıfır olmayan bir ek yüke neden olabilir.
Havuzda gerekenden daha fazla nesne örneği tutmak da çöp toplama işlemine yük bindirir. Nesne havuzları, çöp toplama çağrılarının sayısını azaltır ancak her çağrı için gereken iş miktarını artırır. Bunun nedeni, iş miktarının canlı (ulaşılabilir) bayt sayısıyla orantılı olmasıdır.