Android 17 ve sonraki sürümlerde, Linux cgroup v2'yi kullanarak uygulama işlemlerinin bellek kullanımını izleyen ve 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. Çıkarma ve takas sonucunda uygulama daha yavaş çalışabilir.
En kötü durumda, uygulama anonim bellek ayırmaya devam ederse ve cihazda takas alanı kalmazsa 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şleme 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).
Cihaz bellek sınırı yönergeleri
Cihazınız için bellek sınırlarını yapılandırırken aşağıdaki yönergeleri göz önünde bulundurun:
Sınırları donanım özelliklerine göre ayarlama: Cihaz OEM'leri, cihazlarının donanım özelliklerine göre ayarlanmış sınırlar belirleyebilir. Android aşağıdaki aralıkları önerir:
- Görünür işlemler: Toplam fiziksel RAM'in en az 1/2'si, en fazla 2/3'ü.
- Görünmeyen işlemler: Toplam fiziksel RAM'in 1/4'ü ila 1/3'ü. OEM'ler, cihaz özelliklerine ve kullanım alanlarına göre farklı belirlemeler yapabilir.
Uygulamalar için çalışma zamanı API'si yok: Android 17'den (SDK 37) itibaren uygulamalar, çalışma zamanında bellek sınırlarını sorgulamak için bir API'ye sahip değildir. OEM'ler bunu dikkate almalı ve sınırları çok düşük ayarlamaktan kaçınarak uygulamaların makul kullanım alanlarında sınırlara ulaşmamasını sağlamalıdır.
Evrensel yapılandırma: Sınırlar, önceden yüklenmiş uygulamalar da dahil olmak üzere cihazdaki tüm uygulama süreçleri için geçerlidir. Belirli uygulamaları bu sınırlamaların dışında tutmak için izin verilenler listesi yoktur.
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şlarsa durumuna göre varsayılan sınırlara döner.