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 durumu | Bellek sınırı |
|---|---|
PERSISTENT | Kısıtlanmamış |
PERSISTENT_UI | Kısıtlanmamış |
TOP | Görünür |
BOUND_TOP | Görünür |
FOREGROUND_SERVICE | Görünmez |
BOUND_FOREGROUND_SERVICE | Görünmez |
IMPORTANT_FOREGROUND | Görünür |
IMPORTANT_BACKGROUND | Görünmez |
TRANSIENT_BACKGROUND | Görünmez |
BACKUP | Görünmez |
SERVICE | Görünmez |
RECEIVER | Görünmez |
TOP_SLEEPING | Görünür |
HEAVY_WEIGHT | Görünmez |
HOME | Görünmez |
LAST_ACTIVITY | Gö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.xmlVarsayı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:
- Değiştir'i
/vendor/etc/memory-limiter-config.xmltıklayın. - Değişikliklerin geçerli olması için cihazı yeniden başlatın veya
system_serveruygulaması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.
visibleMemvenotVisibleMem- 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 UIDadb 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 1234adb 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.