Önbelleğe alınan uygulamaları dondurma

Android 11 (API düzeyi 30) veya sonraki sürümlerde önbelleğe alınmış uygulamaları dondurma özelliği desteklenir. Bu özellik, önbelleğe alınmış işlemlerin yürütülmesini durdurur ve önbelleğe alınmış durumdayken çalışmaya çalışan hatalı uygulamaların kaynak kullanımını azaltır.

Önbelleğe alınmış uygulamaları dondurma özelliği, uygulamaları CPU'dan uzak tutarken RAM'de tutar. Android, bir uygulamanın çalışmaması gerektiğini ancak gelecekte gerekebileceğini belirlerse uygulama sürecini sonlandırmak yerine dondurur. Bu, uygulama tekrar gerektiğinde baştan başlatmayı önler.

Android, süreçlerini dondurulmuş bir cgroup'a taşıyarak önbelleğe alınmış uygulamaları dondurur. Bu, etkin olarak önbelleğe alınmış uygulamalar olduğunda etkin ve boşta CPU tüketimini azaltır. Uygulama dondurucuyu sistem yapılandırma işareti veya geliştirici seçeneği kullanarak etkinleştirebilirsiniz.

Android 14 (API düzeyi 34) ve sonraki sürümlerde, önbelleğe alınmış uygulamaları dondurma özelliği aşağıdaki güçlü davranışları içerir:

  • Önbelleğe alınmış durumdaki uygulama işlemleri, önbelleğe alınmış duruma girdikten 10 saniye sonra dondurulur.
  • Sistem, yaşam döngüsü etkinliği sırasında donmuş bir uygulama sürecinin donmasını hemen çözer. Bu etkinlikler arasında amaç alma, iş hizmeti başlatma veya kullanıcının bir etkinliğe devam etmesi yer alır.

ActivityManagerService tüm uygulama işlemlerini yönetir ve uygulama yaşam döngüsüyle ilgili kararlar verir. Uygulama sürecini dondurmaktan CachedAppOptimizer sorumludur.

Bir uygulama süreci dondurulduğunda tüm iş parçacıkları askıya alınır ve dondurulma işlemi kaldırılana kadar CPU çalışması yapamaz. Bu nedenle uygulama, çöp toplama (GC) işlemini gerçekleştiremez ve bellek kırpma etkinliklerine yanıt veremez. Daha fazla bilgi için ComponentCallbacks2.onTrimMemory(int) başlıklı makaleyi inceleyin. Bunu karşılamak için Android 14'ten itibaren:

  • Görünür bir Activity örneği olan uygulamalar, arka plana taşındıkları anda TRIM_MEMORY_UI_HIDDEN hakkında bilgilendirilir. Ön plan hizmeti içeren uygulamalar gibi, kullanıcı arayüzü olmadan yaşam döngüsünde kalan uygulamalar TRIM_MEMORY_BACKGROUND alabilir. Uygulamalar bu etkinliklere uygun olduğunda dondurulmaları beklendiğinden diğer kırpma etkinlikleri yayınlanmaz.
  • Önbelleğe alınmış duruma girdikten kısa süre sonra sistem, dondurulma ihtimaline karşı hazırlık olarak uygulama çalışma zamanından çöp toplama işlemi gerçekleştirmesini isteyebilir.
  • Bir uygulama işlemi dondurulduğunda ek bellek sıkıştırma adımları (ör. kirli sayfaları destekleme depolama alanına yazma ve anonim sayfaları ZRAM'e takas etme) gerçekleşebilir.
  • Belirli bir uygulamayla ilgili tüm işlemler dondurulursa sistem, uygulama tarafından tutulan tüm etkin TCP soketlerini sonlandırır. Bu, soketin sunucu tarafının, cihaz modemini uyandıracak TCP canlı tutma ping'leri göndermesini engeller.

Önbelleğe alınmış uygulama işlemleri, işlem durumları önbelleğe alınmış durumdan daha yüksek öneme sahip bir duruma yükseltildiğinde dondurulmuş durumdan çıkarılır. Android 14 ve sonraki sürümlerde dondurma çözme etkinliklerini azaltmak için sistem, uygulama önbelleğe alınmış durumdayken bağlama kayıtlı yayınları sıraya alır. Bağlamda kayıtlı yayın alıcılar, bir uygulamanın Context.registerReceiver işlevini çağırarak dinamik olarak kaydettiği alıcılardır. Sistem, bu sıraya alınmış yayınları yalnızca uygulama dondurulması kaldırıldıktan sonra yayınlar. Bunun aksine, sistem manifest'te belirtilen yayınları sıraya almaz. Manifest'te belirtilen yayınlar, <receiver> öğesi kullanılarak AndroidManifest.xml içinde statik olarak belirtilen alıcılardır. Sistem, manifestte belirtilen yayınları sunmak için önbelleğe alınan uygulamayı hemen çözdürür.

Sistemin sağlığı üzerindeki etki

Önbelleğe alınmış uygulama işlemleri sayısı MAX_CACHED_PROCESSES'dan fazlaysa Android, en son kullanılan önbelleğe alınmış uygulama işlemini sonlandırır. Android 14 veya sonraki sürümlerin yüklü olduğu desteklenen cihazlarda MAX_CACHED_PROCESSES önemli ölçüde artırılır. Böylece cihazlar, RAM'de çok daha fazla sayıda önbelleğe alınmış uygulama süreci tutabilir.

RAM'de daha fazla uygulamanın önbelleğe alınması, cihazın toplam RAM'ine bağlı olarak ölçeklenen azalmalarla birlikte baştan başlatma sayısında% 30'a varan düşüş sağlar. Aynı zamanda, önbelleğe alınan uygulamaların CPU tüketimi en aza indirilir ve bu da önemli ölçüde pil tasarrufu sağlar.

Dondurucu muafiyetleri

Belirli koşullar altında, bir uygulama işlemi önbelleğe alınmış duruma girebilir ancak dondurulmamış olarak kalabilir. Bu muafiyetler uygulama ayrıntılarıdır ve gelecekteki Android sürümlerinde değişebilir:

  • Dosya kilitleri: Önbelleğe alınmış bir işlem, diğer önbelleğe alınmamış işlemleri engelleyen bir dosya kilidi tutuyorsa kilidi tutan işlem dondurulmaz.
  • BIND_WAIVE_PRIORITY bağlamaları: Context.BIND_WAIVE_PRIORITY kullanılarak oluşturulan, gelen bağlamaları olan uygulama işlemleri önbelleğe alınmış duruma girebilir ancak bağlı tüm istemci işlemleri de önbelleğe alınana kadar dondurulmaz. Bu muafiyet, özel sekmeleri kullanan web tarayıcıları gibi çok işlemli uygulamaları destekler.

Uygulama dondurucuyu kullanma

Önbelleğe alınmış uygulamaları dondurucu, çekirdek cgroup v2 dondurucusunu kullanır. Uyumlu çekirdekle birlikte gelen cihazlarda etkinleştirilebilir. Önbelleğe alınmış uygulamalar için yürütmeyi askıya al geliştirici seçeneğini etkinleştirin veya cihaz yapılandırma flag'ini activity_manager_native_boot use_freezer olarak true ayarlayın. Örneğin:

adb shell device_config put activity_manager_native_boot use_freezer true && adb reboot

use_freezer işaretini false olarak ayarladığınızda veya geliştirici seçeneğini devre dışı bıraktığınızda dondurucu devre dışı bırakılır. Örneğin:

adb shell device_config put activity_manager_native_boot use_freezer false && adb reboot

Bu ayarı, bir yazılım sürümünde veya güncellemesinde cihaz yapılandırmasını değiştirerek açıp kapatabilirsiniz.

MAX_CACHED_PROCESSES'yı geçersiz kılmak için (ör. test amacıyla değeri 1024 olarak ayarlamak için):

adb shell device_config put activity_manager max_cached_processes 1024
adb shell device_config set_sync_disabled_for_tests persistent

MAX_CACHED_PROCESSES geçersiz kılmayı geri almak için:

adb shell device_config delete activity_manager max_cached_processes
adb shell device_config set_sync_disabled_for_tests none

Android 16 (API düzeyi 36) ve sonraki sürümlerde Android, uzak işlemlerin dondurulup dondurulmadığını veya çözülüp çözülmediğini gözlemlemek için IBinder.FrozenStateChangeCallback ve IBinder.addFrozenStateChangeCallback gibi resmi genel API'ler sağlar. Önbelleğe alınabilecek uygulamalarla etkileşimde bulunan bileşenler, uzak işlemlerin dondurulmuş durumunu izlemek için bu API'leri kullanabilir.

Cihaz ve çekirdek gereksinimleri

Önbelleğe alınmış uygulamaları dondurma özelliği için çekirdek cgroup v2 desteği gerekir. Ayrıca, IBinder.FrozenStateChangeCallback kullanılarak dondurma durumu değişikliği bildirimleri için çekirdek bağlayıcı sürücüsü desteği gerekir. Bu destek, Android 14 (API düzeyi 34) ve sonraki sürümlerden itibaren Android Common Kernels (ACK) ve Generic Kernel Images (GKI) içinde standart olarak bulunur.

Bir cihazın bu özellikleri destekleyip desteklemediğini standart adb komutlarını kullanarak aşağıdaki şekilde doğrulayabilirsiniz:

  • Cihazda dondurucunun etkin olup olmadığını kontrol edin (kullanıcı veya hata ayıklama derlemeleri için):

    adb shell device_config get activity_manager_native_boot use_freezer

    Alternatif olarak, işlemlerin sistem tarafından etkin bir şekilde dondurulduğunu doğrulayın:

    adb shell dumpsys activity | grep -A 20 "Apps frozen:"
  • cgroup v2 dondurucu denetleyici desteğini kontrol etme (tüm cihazlar için):

    freezer öğesinin, kullanılabilir cgroup v2 denetleyicileri arasında listelendiğini doğrulayın:

    adb shell cat /sys/fs/cgroup/cgroup.controllers

    Alternatif olarak, root erişimi olan bir cihazda veya userdebug derlemesinde, cgroup v2 dondurucu düğümünün bir alt cgroup'a monte edildiğini doğrulayın:

    adb root && adb shell ls /sys/fs/cgroup/uid_0/cgroup.freeze

    Bu dosya varsa çekirdek, cgroup v2 dondurucuyu destekler.

  • Dondurma durumu değişikliği bildirim desteğini kontrol etme (herhangi bir cihaz için):

    Android 14 ve sonraki sürümlerin yüklü olduğu, uyumlu Generic Kernel Image (GKI) bağlayıcı sürücülerine sahip cihazlarda, IBinder.addFrozenStateChangeCallback geri çağırmalar başarıyla kaydedilir. Temel çekirdek bağlayıcı sürücüsü dondurma bildirimlerini desteklemiyorsa yöntem UnsupportedOperationException oluşturur.

Özel özellikleri işleme

Uygulama işlemleri, önbelleğe alındığında herhangi bir işlem yapmaz. Ancak bazı uygulamalarda, önbelleğe alınmış durumdayken çalışması beklenen işlemler tarafından desteklenen özel özellikler olabilir. Bu tür uygulamaların çalıştığı bir cihazda uygulama dondurucu etkinleştirildiğinde, önbelleğe alınmış işlemler dondurulur ve özel özelliklerin çalışmasını engelleyebilir.

Geçici çözüm olarak, işlem herhangi bir iş yapmadan önce işlem durumunu önbelleğe alınmamış olarak değiştirebilirsiniz. Bu değişiklik, uygulamaların etkin kalmasına olanak tanır. Etkin durumlara örnek olarak bağlı bir ön plan hizmeti veya ön plan durumu verilebilir.

Sık karşılaşılan arıza modları

Uygulama süreçleri dondurulduğunda, süreçler arası uygunsuz iletişim (IPC) veya görev planlama, uygulamaların sonlandırılmasına ya da beklenmedik davranışlara yol açabilir.

Dondurulmuş süreçlere eşzamanlı bağlayıcı işlemleri

Bir istemci uygulaması işlemi, dondurulmuş bir sunucu uygulaması işlemine senkron bağlayıcı işlemi gönderdiğinde sistem, sunucu uygulaması işlemini hemen sonlandırır. Bu, dondurulmuş sunucudan yanıt beklerken istemci iş parçacığının süresiz olarak engellenmesini önler. Ardından, istemci iş parçacığı RemoteException alır ve kayıtlı tüm dinleyiciler tetiklenir. Daha fazla bilgi için IBinder.linkToDeath başlıklı makaleyi inceleyin.

Temel neden: Bu hata genellikle istemci uygulamasındaki bir hatadan kaynaklanır. Bir istemci bir hizmete bağlandığında sunucu işlemi istemciye bağlanır ve istemci bunu yapmadan önce önbelleğe alınmış duruma girmesi engellenir. Daha fazla bilgi için Context.bindService başlıklı makaleyi inceleyin. Ancak istemci Context.unbindService işlevini çağırdığında sunucu işlemi önbelleğe alınabilir ve dondurulabilir. İstemci, bağlama kaldırıldıktan sonra önbelleğe alınmış IBinder referansını kullanmaya devam ederse donmuş bir süreçle iletişim kurma riskiyle karşı karşıya kalır.

Bu sorunu önlemek için istemci uygulamalarının IBinder referanslarını Context.unbindService çağrıldıktan hemen sonra silmesini sağlayın.

İstemci işlemlerine yönelik uzaktan geri aramaları yönetme

İstemci süreçlerine uzun süreli bağlayıcı geri aramaları sürdüren hizmetler ve sistem bileşenleri, istemcinin dondurulmuş durumunu izleyerek senkron hataları ve asenkron arabellek taşmalarını önleyebilir:

  • Durum değişikliği dinleyicisi kaydetme: İstemci işlemi dondurucuya girdiğinde veya dondurucudan çıktığında bildirim almak için gelen istemci bağlayıcı jetonlarında IBinder.addFrozenStateChangeCallback kullanın.
  • Dondurulmuş durumdayken göndermeyi duraklat: Bir istemci STATE_FROZEN girdiğinde, bu istemciye geri çağırma veya durum güncellemelerinin gönderilmesini duraklatın.
  • Dondurma kaldırıldığında devam ettirme ve teslim etme: Müşteri STATE_UNFROZEN'a geçtiğinde geri arama dağıtımına devam edin ve gerekli tüm toplu veya birleştirilmiş güncellemeleri teslim edin.
  • RemoteCallbackList'i kullanma: RemoteCallbackList kullanan sistem hizmetleri, manuel izleme mantığını korumadan geri çağırma göndermeyi otomatik olarak duraklatmak ve devam ettirmek için dondurulmuş aranan politikalarını yapılandırabilir. Daha fazla bilgi için Sistem hizmetleri için bağlayıcı dondurma önerileri başlıklı makaleyi inceleyin.

Eşzamansız ciltleyici işlem arabellek taşması

Bir sunucu uygulaması işlemi dondurulmuş durumdayken eşzamansız (oneway) bağlayıcı işlemleri aldığında, işlemler süreç başına arabellekte arabelleğe alınır. Sunucu, dondurulmuş durumdayken çok fazla eşzamansız işlem alırsa arabellek taşar ve sistem, sunucu uygulaması sürecini sonlandırır.

Bu arabellek taşmasını önlemek için, önbelleğe alınmış veya dondurulmuş olabilecek işlemlere aşırı sayıda eşzamansız bağlayıcı işlemi göndermeyin.

Dondurma işlemi kaldırıldıktan sonra planlanmış görevlerin tekrar tekrar yürütülmesi

Bir uygulama tekrarlanan görevler yürütüyorsa işlem dondurulurken bu görevler askıya alınır. Daha fazla bilgi için ScheduledThreadPoolExecutor.scheduleAtFixedRate veya Timer.scheduleAtFixedRate başlıklı makaleyi inceleyin. Süreç dondurulması kaldırıldığında, biriken kaçırılan yürütmeler neredeyse hiç gecikme olmadan hızlı bir şekilde arka arkaya çalışabilir.

Uygulamanın dondurulması kaldırıldığında yürütme işlemlerinin artmasını önlemek için arka plan görevlerinde scheduleAtFixedRate yerine scheduleWithFixedDelay kullanın. WorkManager adresini de kullanabilirsiniz.

Uygulama dondurucuyu test etme ve sorunlarını giderme

Uygulama dondurucunun beklendiği gibi çalıştığını doğrulamak veya dondurucuyla ilgili sorunları gidermek için aşağıdaki teşhis araçlarını ve komutlarını kullanın:

Etkinlik yöneticisi komutları

Belirli bir işlem için dondurma ve sıkıştırmayı manuel olarak kontrol etmek üzere adb shell am komutlarını kullanabilirsiniz:

  • Bir işlemi dondurmaya zorlama:

    adb shell am freeze <process>
  • Bir işlemin dondurulmasını zorla kaldırma:

    adb shell am unfreeze <process>
  • Bir süreçte tam bellek sıkıştırması zorlama:

    adb shell am compact full <process>

Logcat incelemesi

Bir işlem dondurucuya her taşındığında veya dondurucudan her çıkarıldığında dondurulmuş ve dondurulmamış girişleri görmek için logcat'i görüntüleyin:

adb logcat | grep -i "\(freezing\|froze\)"

Dondurmayı kaldırma nedeni günlükleri, UnfreezeReason protokolü arabelleği enum'ından numaralandırılmış değerler çıkarır.

Dumpsys incelemesi

dumpsys activity kullanarak dondurulmuş işlemlerin listesini kontrol edin:

adb shell dumpsys activity | grep -A 20 "Apps frozen:"

/sys/fs/cgroup/uid_0/cgroup.freeze dosyasının olup olmadığını kontrol edin.

ApplicationExitInfo

Önceki bir işlem kapatma nedenini sorgulamak için ActivityManager.getHistoricalProcessExitReasons başlıklı makaleyi inceleyin. Bir uygulama işlemi, donmayla ilgili bir sorun nedeniyle sonlandırıldıysa (ör. donmuş durumdayken senkron bağlayıcı işlemi alma) çıkış nedeni ApplicationExitInfo.REASON_FREEZER olarak ayarlanır.

Perfetto izleme

Dondurucuyla ilgili etkinlikler, Perfetto izlemelerindeki system_server işlemi altında Freezer adlı bir kanala gönderilir:

  • Freeze ve Unfreeze dilimleri, bir işlemin durumunun ne zaman değiştiğini gösterir.
  • updateAppFreezeStateLSP etkinlikleri, sistem sunucusu dondurma veya çözme kararları vermek için işlem özelliklerini yeniden incelediğinde gösterilir.

Bu etkinlikleri doğrudan Perfetto kullanıcı arayüzünde inceleyebilir veya PerfettoSQL kullanarak analiz edebilirsiniz:

INCLUDE PERFETTO MODULE slices.with_context;
SELECT *
FROM process_slice
WHERE process_name = "system_server"
AND track_name = "Freezer"
AND (name LIKE "Freeze %" OR name LIKE "Unfreeze %");

PerfettoSQL standart kitaplığında, dondurucu etkinlikleri android_freezer_events tablosunda da özetlenir.