Bellek sınırlayıcı

Android 17 ve sonraki sürümlerde, Linux cgroup v2'yi kullanan uygulama işlemlerinin bellek kullanımını izleyip sınırlayan bir sisteme ait hizmet olan bellek sınırlayıcı desteklenir. Bellek sınırlayıcı, tek tek uygulamaların aşırı sistem belleği tüketmesini önleyerek sistem genelinde bellek baskısını azaltır ve kritik işlemlerin agresif bir şekilde bellek yetersizliği (OOM) nedeniyle sonlandırılmasını engeller.

Mekanizma

Bellek sınırlayıcı, işlem yaşam döngüsü etkinliklerini ve durum değişikliklerini izlemek için Etkinlik Yöneticisi Hizmeti (AMS) ile entegre olur. Bellek sınırlayıcı, Linux çekirdeği cgroup v2 dosya sistemini kullanarak bellek sınırlarını zorunlu kılar.

Bellek sınırlayıcıyı kullanmak için cihaz çekirdeğinin cgroup v2'yi ve memory denetleyiciyi desteklemesi gerekir. Hizmet özellikle aşağıdaki özelliklere dayanır:

memory.high
Sanal sınır. Bu sınır aşıldığında işlem kısıtlanır ve çekirdek, bellek geri kazanmaya çalışır.
memory.swap.max
İşlemin kullanabileceği takas alanı miktarını sınırlar.

Uygulamalar üzerindeki etkisi

Bellek sınırlarını aşmayan uygulamalar, bellek sınırlayıcıdan etkilenmez.

Bir uygulama memory.high sınırını aştığında çekirdek, uygulamayı sınır içinde tutmak için uygulamanın dosya destekli belleğini çıkarır ve anonim belleğini değiştirir. Tahliye ve takas sonucunda uygulama daha yavaş çalışabilir.

En kötü durumda, uygulama anonim bellek ayırmaya devam ederse ve cihazın takas alanı biterse uygulama bellek ayıramayabilir ve sonuç olarak kilitlenmesi olasıdır.

Süreç izleme

Bellek sınırlayıcı, varsayılan olarak uygulama işlemlerini (UID >= 10000) izler. Sistem süreçleri, temel sistem kararlılığını doğrulamaya yardımcı olmak için genellikle muaf tutulur.

Bellek sınırlayıcı, işlem durumuna göre bellek sınırları atar:

  • Görünür işlemler, kullanıcı tarafından algılanabilir. Örneğin, ön plan etkinlikleri, ön plan hizmetleri veya diğer takılma algılanabilir durumlar.

  • Görünmeyen işlemler, kullanıcıyla etkileşimde bulunmayan veya kullanıcıya görünmeyen arka plan işlemleridir.

Aşağıdaki tabloda belirli işlem durumları bellek sınırlarıyla eşleştirilmiştir:

İşlem durumuBellek sınırı
PERSISTENTKısıtlanmamış
PERSISTENT_UIKısıtlanmamış
TOPGörünür
BOUND_TOPGörünür
FOREGROUND_SERVICEGörünmez
BOUND_FOREGROUND_SERVICEGörünmez
IMPORTANT_FOREGROUNDGörünür
IMPORTANT_BACKGROUNDGörünmez
TRANSIENT_BACKGROUNDGörünmez
BACKUPGörünmez
SERVICEGörünmez
RECEIVERGörünmez
TOP_SLEEPINGGörünür
HEAVY_WEIGHTGörünmez
HOMEGörünmez
LAST_ACTIVITYGörünmez
CACHED_ACTIVITYÖnbelleğe alındı
CACHED_ACTIVITY_CLIENTÖnbelleğe alındı
CACHED_RECENTÖnbelleğe alındı
CACHED_EMPTYÖnbelleğe alındı

Önbelleğe alınmış durumda işlemler dondurulur ve ardından en üst düzeyde geri kazanılır.

Bir işlem, kendisine atanan memory.high sınırını aştığında bellek sınırlayıcı bu durumu algılar ve bellek profili yakalama veya statsd'ye anormallik kaydetme gibi hata ayıklama işlemlerini tetikleyebilir.

Yapılandırma

vendor bölümünde bulunan bir XML dosyası kullanarak bellek sınırlayıcıyı yapılandırın. Yapılandırma, mutlak bellek sınırlarını cihazın belirli bellek kısıtlamalarına göre ayarlamanıza olanak tanır.

  • Dosya yolu: /vendor/etc/memory-limiter-config.xml

  • Varsayılan yapılandırma: Yapılandırma dosyası bulunamazsa veya okunamaz ya da geçersizse bellek sınırlayıcı devre dışı bırakılır.

XML biçimi

Yapılandırma dosyası, memory-limiter-config.xsd içinde tanımlanan şemaya uygundur. Bu dosya, birden fazla sınır grubu tanımlamanıza olanak tanır. Hizmet, cihazın kullanılabilir RAM'ine göre en iyi eşleşmeyi seçer. Tüm bellek değerleri mebibayt (MiB) birimleriyle tanımlanır.

<MemoryLimiterConfig>
  <version>1</version>
  <configList>
    <limitSet>
      <!-- Limits for a phone with at least 14G of ram: 8G/4G/4G/4G -->
      <minimumRequiredMemTotal>14336</minimumRequiredMemTotal>
      <memVisible>8192</memVisible>
      <memNotVisible>4096</memNotVisible>
      <swapVisible>4096</swapVisible>
      <swapNotVisible>4096</swapNotVisible>
    </limitSet>
  </configList>
</MemoryLimiterConfig>
version
Yapılandırma sürümünü tanımlayan pozitif tam sayı. Bu değer 1 olmalıdır.
minimumRequiredMemTotal
Bu sınırın geçerli olması için gereken minimum kullanılabilir sistem belleği.
memVisible
Görünür işlemler için izin verilen bellek sınırı (memory.high).
memNotVisible
Görünür olmayan işlemler için izin verilen bellek sınırı (memory.high).
swapVisible
Görünür işlemler için izin verilen takas sınırı (memory.swap.max).
swapNotVisible
Görünür olmayan işlemler için izin verilen takas sınırı (memory.swap.max).

Yapılandırmayı değiştirme

Sistem genelindeki sınırları değiştirmek için aşağıdaki adımları uygulayın:

  1. Değiştir'i /vendor/etc/memory-limiter-config.xml tıklayın.
  2. Değişikliklerin geçerli olması için cihazı yeniden başlatın veya system_server uygulamasını yeniden başlatın.

Kabuk komutları

am memory-limiter komutu, geliştirme ve test için çalışma zamanında hizmetle etkileşim kurmanıza olanak tanır:

am memory-limiter <SUB-COMMAND>

durum

status alt komutu, bellek sınırlayıcının operasyonel durumunu bildirir:

adb shell am memory-limiter status

Örnek çıkış:

Memory limiter
  enabled                  monitoring=true          ignored=none
  visibleMem=1948MB        visibleSwap=974MB
  notVisibleMem=974MB      notVisibleSwap=487MB
  started=36               watched=36               watch-failed=0
  events=0                 processes=36             process-hwm=36

Çıkıştaki temel alanlar şunlardır:

monitoring
Sınırlayıcının işlemleri etkin olarak izleyip izlemediğini gösterir.
visibleMem ve notVisibleMem
Her durum için hesaplanan mutlak bellek sınırlarını belirtin.
events
Bir işlemin sınırını aşma sayısı.
processes
İzlenen işlemlerin sayısı.

yoksay

ignore alt komutu, bir UID'yi veya tüm işlemleri geçici olarak sınırlamadan hariç tutar. Bu işlem, performans testi için veya belirli bir uygulamanın sınırlarını aşmasına izin vermek istediğinizde kullanışlıdır.

adb shell am memory-limiter ignore 10087  // Ignore a specific UID
adb shell am memory-limiter ignore all    // Ignore all processes (effectively disables limiting)
adb shell am memory-limiter ignore none   // Resume normal operation

manuel

manual alt komutu, belirli bir işlem için (işlem kimliği veya PID'ye göre) hesaplanan sınırları megabayt (MB) cinsinden özel bir mutlak değerle geçersiz kılar:

adb shell am memory-limiter manual 1234 1024   // Set a 1024 MB limit for PID 1234
adb shell am memory-limiter manual 1234 none // Remove the manual override for PID 1234

Manuel geçersiz kılmalar yalnızca sürecin yaşam döngüsü için geçerlidir. İşlem yeniden başlatılırsa durumuna göre varsayılan sınırlara döner.