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. Fiziksel belleğin genellikle sınırlı olduğu mobil işletim sistemlerinde ise daha da değerlidir. Android Çalışma Zamanı (ART) ve Dalvik sanal makinesi rutin atık 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 bellek sızıntılarına neden olmaktan (genellikle statik üye değişkenlerindeki nesne referanslarını tutmaktan kaynaklanır) kaçınmanız ve yaşam döngüsü geri çağırma işlemleri tarafından tanımlandığı şekilde uygun zamanda Reference nesnelerini serbest bırakmanız gerekir.
Uygulamanızın kod ve kaynak ayak izini küçültme
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ı bellek alanınızın 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 kapladığı yeri 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, uygulamanızın bayt kodunu analiz ederek kullanılmayan kodları kaldırır, gereksiz sınıfları birleştirir, yöntemleri satır içi yapar ve tanımlayıcıları küçültür. APK'dan RAM'e daha az derlenmiş bayt kod yükleyerek uygulamanın genel taban bellekte kaplanan yerini azaltır. Ayrıca sınıf, yöntem ve alan adlarını kısaltılmış tanımlayıcılara küçültmek doğrudan RAM yükünü azaltır. Sınıf birleştirme ve kapsamlı yöntem satır içi ekleme gibi optimizasyonlar, maliyetli çalışma zamanı aramalarının ve ayırma kalıplarının yerini alarak 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ını kullanmayla 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 kütüphaneleri 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 alanı 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.
R8 kullanarak uygulamanızı optimize etmek, bağımlılıklardaki kullanılmayan kodu kaldırabilir ancak bu işlemin etkinliği genellikle kitaplığın dahili yapılandırmasıyla sınırlıdır. Örneğin, geniş kapsamlı saklama kuralları veya bir kitaplıkta yansıtma kullanılması, R8'in kodunu küçültmesini engelleyebilir ve bu da daha büyük bir bellek alanı oluşturur. Verimli kitaplıklar seçme stratejileri için Kitaplıkları akıllıca seçme 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ü çekmeyin. 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 tekniğini 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. Daha fazla bilgi için kapsamlı nesnelerle bellek sızıntılarını önleme hakkındaki kılavuza bakın.
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şlem olarak genişletilmesi gerekir. Küçük bir sıkıştırılmış resim dosyası çok büyük bir bit eşleme dosyasına dönüşebilir.
Ö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 dosyanız 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ı, aşağıdaki şekillerde bellek sorunlarını 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 izleme (stack trace) 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 konusunda 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 bellek eşiği (sistemin işlemleri durdurmaya başladığı bellek düzeyi) 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ı tarafından algılanan düşük bellek nedeniyle işlem sonlandırma (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 puanları alır 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.
Android Vitals'da ön plan işlemlerinin sonlandırılmasına öncelik verilir. Bunun nedeni, bu işlemlerin bellek yönetimiyle ilgili sorunlar için yüksek doğrulukta bir vekil görevi görmesidir. %1'ten yüksek bir LMK oranı, acil işlem yapılması gerektiğini gösterse de düşük bir oran, hesabın sağlıklı olduğu anlamına gelmez. Kullanıcı tarafından algılanan LMK oranının düşük olması, LMK arka plan programının arka planda çalışan işlemleri sık sık sonlandırdığı anlamına gelebilir. Bu durum, "hazır durumda 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 simgesini kullanın.
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 işlem, yeniden üretilmesi zor olan bellek sorunlarını belirlemenize yardımcı olabilir.
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. Uygulama, kilitlenmeden sonraki başlatılışında profil oluşturma tetikleyicileri için kaydolduğunda tetiklenir.TRIGGER_TYPE_ANOMALYSistem, uygulamada anormal davranış algıladığında tetiklenir. Bu durum, diğer nedenlerin yanı sıra aşırı bellek kullanımıyla da tetiklenebilir. Bu uyarı, uygulama aşırı bellek kullanımı gösterdikten sonra ve sistem, hataya neden olan 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şıyorsaTRIGGER_TYPE_ANOMALY, sistem uygulamayı kapatmadan önce tetiklenir.
ProfilingManager kullanarak tetikleyicileri programatik olarak kaydetme ve alma hakkında daha fazla bilgi için tetikleyici tabanlı profilleme belgelerine bakın.
Ayrıca, uygulama odaklı profillemeyi kullanarak izleme başlangıç ve bitiş noktalarını manuel olarak da tanımlayabilirsiniz. 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 işlemi yapmanızı öneririz.
Daha fazla bellek verimliliği sağlayan 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 kullanma
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ışır durumda bırakmayın. 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 işlemlerini çok pahalı 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ırmak için yeterli sayıda işlem sürdüremediğinde sistemde aşırı bellek kullanımına yol açabilir.
Genel olarak, kullanılabilir bellek üzerinde sürekli talepleri olduğu için kalıcı hizmetleri kullanmaktan kaçının. Bunun yerine WorkManager gibi alternatif bir uygulama kullanmanızı öneririz.
Arka plan işlemlerini planlamak için WorkManager simgesinin nasıl kullanılacağı hakkında daha fazla bilgi edinmek için Kalıcı iş 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ı, sistemin anahtarı ve bazen de değeri otomatik olarak kutulaması gerekmediğinden daha verimlidir. Bu durum, 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 daha büyük olması, uygulamanızın ihtiyaç duyduğu fiziksel RAM'i doğrudan artırır. Soyutlamalarınız önemli ölçüde faydalı değilse bunlardan kaçının.
Serileştirilmiş veriler için lite protobuf'ları kullanma
Protokol arabellekleri (protobufs), 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 ayak izini artırır (bkz. Uygulamanızın kod ayak izini yönetme ve optimize etme) 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
Referansların uygun şekilde yönetilmemesi, nesnelerin yararlı ömürlerinden daha uzun süre yaşamasına neden olan 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.
Daha fazla bilgi için Bellek sızıntıları başlıklı makaleyi inceleyin.
Bellek karmaşıklığından kaçının
Atık toplama etkinlikleri, uygulamanızın performansını etkilemez. Ancak kısa bir süre içinde gerçekleşen birçok atık toplama etkinliği, pilin hızla tükenmesine ve atık toplayıcı ile uygulama iş parçacıkları arasındaki gerekli etkileşimler nedeniyle karelerin ayarlanma süresinin biraz artmasına neden olabilir. Sistem, atık toplama işlemine ne kadar çok zaman harcarsa pil o kadar hızlı biter.
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 Paint veya Bitmap işlevi içinde yeni onDraw() 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 önemli alanlardaki ayırma sayısını azaltmaya çalışın. Öğeleri iç döngülerden çıkarmayı veya fabrika tabanlı bir tahsis yapısına taşımayı deneyin.
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ç duyduğunuzda, onu ayırmak yerine havuzdan alabilirsiniz.
Bir nesne havuzunun belirli bir durumda uygun olup olmadığını belirlemek için performansı ayrıntılı bir şekilde 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 senkronizasyonu içerir ve bu da önemli bir ek yük oluşturur. Ayrıca, yayın 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 atık toplama işlemine yük bindirir. Nesne havuzları çöp toplama çağrılarının sayısını azaltırken canlı (ulaşılabilir) bayt sayısıyla orantılı olduğundan her çağrı için gereken iş miktarını artırır.