Android 17 ve sonraki sürümlerde platform, genel uygulama Bellek Sınırlayıcı ile birlikte çalışan iki tamamlayıcı Linux cgroup v2 mekanizmasını kullanarak sistem işlemi belleğini yönetir:
- Sistem arka plan programı koruma katmanları (
memory.minileSystemMemoryBudgetManager):com.android.server.am.system_process_memory_budgetsözellik bayrağı tarafından etkinleştirildiğinde (ilk Android 17 sürümünde varsayılan olarak devre dışıdır), kendi kendini ayarlayan cgroup v2memory.minayırmaları (her arka plan programının yerleşik yerleşik çalışma kümesinin %90'ına ayarlanır ve toplam fiziksel RAM'in %10'u ile sınırlıdır) bellek baskısı altında kritik etkileşimli arka plan programlarını ve kabuk işlemlerini (system_server,surfaceflinger, grafikcomposerHAL,audioserver,cameraserver,netd,SystemUIve ana ekran başlatıcı) korur ve statikPinnerServicemlockdosya sabitlemenin yerini alır. - Sistem uygulaması bellek tavanları (
memory.highile<memory-budget>): Kalıcı ve arka plan sistem uygulamaları (Bluetooth,Nfc,CalendarProvider,Traceur,MediaProvider,:PhotoPicker,NetworkStack,AppSearchveTeleService) için manifest dosyalarında beyan edilen iş yüküne göre kalibre edilmiş cgroup v2memory.highesnek sınırları (genellikle 30 MB ila 190 MB), genel bellek baskısı oluşmadan önce soğuk dosya sayfası önbelleğini ve patlama sonrası anonim yığını proaktif olarak geri alır.
Aşağıdaki tabloda iki mekanizma karşılaştırılmaktadır:
| Boyut | Sistem arka plan programı koruma katları | Sistem uygulaması bellek tavanları |
|---|---|---|
| Platform hizmeti | SystemMemoryBudgetManager |
MemoryLimiter |
| Cgroup v2 kontrolü | memory.min sert koruma tabanı |
memory.high esnek geri alma tavanı |
| Hedef süreçler | Gecikme açısından kritik etkileşimli daemon'lar ve kabuk kullanıcı arayüzü (system_server, surfaceflinger, composer HAL, audioserver, cameraserver, netd, SystemUI ve Home uygulaması) |
Kalıcı ve başsız sistem uygulamaları, içerik sağlayıcılar ve arka plan hizmetleri (ör. Bluetooth, Nfc, MediaProvider, NetworkStack, AppSearch ve TeleService) |
| Boyutlandırma modeli | Çalışma zamanında kendi kendine ayarlama (yerleşik çalışma setinin %90'ı, toplam RAM'in %10'u ile genel olarak sınırlıdır) ve cihaz başına sıfır ayarlama tablosu | RAM katmanı, işlem durumu ve ekran piksel sayısına göre kalibre edilmiş açıklayıcı <memory-budget> manifest XML özellikleri |
| Temel avantaj | Statik PinnerService mlock dosya listelerini değiştirirken bellek baskısı altında etkileşimli kullanıcı arayüzü takılmalarını ve uyanma duraklamalarını önler. |
Ön plandaki ve önbelleğe alınmış uygulamalar için daha fazla fiziksel RAM bırakmak amacıyla, soğuk tek seferlik dosya önbelleğini ve patlama sonrası yığını sürekli olarak çıkarır. |
<memory-budget> söz dizimi, XML özellikleri, çalışma zamanı API'leri ve işletim sistemi bellek hesaplaması hakkında daha fazla bilgi için Uygulama bellek bütçelerini ayarlama ve Android belleğini anlama ve sorunlarını giderme başlıklı makaleleri inceleyin.
SystemMemoryBudgetManager ile kritik etkileşimli daemon'ları koruma
SystemMemoryBudgetManager, bellek baskısı sırasında doğrudan kullanıcının etkileşimli yolunda bulunan işlemleri fiziksel RAM'de tutar. mlock ile APK, ODEX ve VDEX dosyalarının statik bir listesini belleğe sabitlemek yerine (PinnerService'nin config_defaultPinnerServiceFiles ve config_pinnerHomePinBytes için yaptığı gibi), SystemMemoryBudgetManager aşağıdaki işlemlere dinamik cgroup v2 memory.min katları atar:
- Çekirdek sistem dilimi (
/sys/fs/cgroup/system):system_server,surfaceflinger, grafikcomposerHAL,audioserver,cameraservervenetdile birlikteconfig_systemMemoryBudgetAdditionalSystemProcessesiçinde listelenen, form faktörüne özgü yerel sistem veya tedarikçi arka plan programları (ör. XR cihazlardaandroid.hardware.perceptionhostveauracamerahal). - Etkileşimli uygulama dilimi (
/sys/fs/cgroup/apps): Yapılandırılmış SystemUI paketinin (config_systemUi) ana işlemi ve mevcut kullanıcının Ana Sayfa rolü sahibinin ana işlemi.
config_systemUi ile birlikte Ana Sayfa rolü sahibini korumak, tüm form faktörlerinde kapsam sağlar. config_systemUi'in hafif bir uyumluluk paketi olduğu form faktörlerinde (ör. kadran, bildirimler ve kutuların Home uygulamasında çalıştığı Wear OS) kullanıcıya yönelik kabuk, tam çalışma seti koruması almaya devam eder. Home intent'i config_systemUi paketine çözümlenirse işlem bir kez korunur. Yalnızca her paketin ana işlemi (processName == packageName) koruma tabanı alır. Bu nedenle, yardımcı alt işlemler (ör. :screenshot) koruma bütçesini tüketmez.
Kendi kendini ayarlayan politika ve üç düzeyli cgroup yetkilendirmesi
Etkileşimli bir arka plan programının çalışma grubu, form faktörlerine ve RAM kapasitelerine göre büyük farklılıklar gösterdiğinden (örneğin, SystemUI akıllı saatte yaklaşık 45 MB, 6 GB'lık bir telefonda 60 MB ve 16 GB'lık bir telefonda 180 MB kullanır) cihaz başına statik arama tabloları hassastır. Bunun yerine, SystemMemoryBudgetManager, üç sabit kullanarak her işlemin kendi yerleşik ayak izinden doğrudan tabanlar türetir:
| Politika parametresi | Varsayılan değer | Davranış |
|---|---|---|
| İşlem başına taban fiyat | Eşlenmemiş dosya önbelleği hariç, kapatılan memory.current tutarının %90'ı |
Anonim yığın, slab ve sıcak eşlenmiş kodu korurken en soğuk %10'luk kısmı geri kazanılabilir durumda bırakır. Böylece gerçekten soğuk sayfalar yine de çıkarılabilir. Eşlenmemiş dosya önbelleği (memory.stat üzerinden max(0, file - shmem - file_mapped)), %90 oranı uygulanmadan önce çıkarılır. Böylece, önyükleme paketi tarama önbelleği veya tek seferlik öğe okumaları alt sınırları artırmaz. |
| Global RAM sınırı | Toplam RAM'in %10'u (config_systemMemoryBudgetLowKb) |
PinnerService config_pinnerMaxPinnedMemoryPercentage güvenlik önlemiyle eşleşiyor. %90'lık tabanların toplamı MemTotal değerinin %10'unu aşarsa her taban aynı çarpanla orantılı olarak ölçeklendirilir. |
| Yenileme sıklığı | Başlangıçtan 1, 4, 16 ve 64 saniye sonra, ardından her 30 dakikada bir | Geometrik bir yerleşim serisi, her cihaz için ısınma gecikmelerini sabit kodlamadan her bir arka plan programının başlangıç sonrası çalışma grubunda birleşir ve 30 dakikalık sabit durum yenilemesi, cihazın kullanım ömrü boyunca çalışma grubunun kademeli olarak büyümesini ve küçülmesini izler. |
Linux cgroup v2 bellek denetleyicisinde (mm/memcontrol.c:effective_protection), bir yaprak cgroup'un etkin memory.min koruması, üst ve ata cgroup'larında yapılandırılan memory.min ile sınırlıdır. uid_<uid>/memory.min, 0 iken memory.min politikasını yalnızca bir yaprak pid_<pid> dizininde ayarlamak, etkin korumanın sıfır olmasına neden olur.
Bunun aksine, yalnızca en üstteki /sys/fs/cgroup/system diliminde sabit bir memory.min ayarlamak, talep edilmeyen korumayı tüm alt UID'lere ve işlemlere orantılı olarak dağıtır (memory_recursiveprot). Bu da uid_1000 (android.uid.system) paylaşan teşhis veya ikincil işlemlerin surfaceflinger ve audioserver'dan korumayı almasına olanak tanır.
Tam arka plan programı izolasyonu sağlamak için SystemMemoryBudgetManager, her yenilemede cgroup v2 hiyerarşisinin üç düzeyinde de koruma yazar (Şekil 1'de gösterildiği gibi):
- Yaprak işlem düğümü (
pid_<pid>/memory.min): İşlemin (ölçeklendirilmiş) %90 çalışma kümesi tabanına ayarlanır. - UID düğümü (
uid_<uid>/memory.min): Yönetilen yaprak katmanlarının tam toplamına ayarlanır. Böylece, bu UID'yi paylaşan yönetilmeyen işlemler (diğerAID_SYSTEMdaemon'lar veyasharedUserId="android.uid.system"paketleri gibi)memory.min = 0olur ve koruma talep edemez.pid_* - Üst düzey dilim (
/sys/fs/cgroup/system/memory.minve/sys/fs/cgroup/apps/memory.min):uid_*alt öğelerinin tam toplamına ayarlanır. Yönetilen düğümlerdeki eskimemory.lowdeğerleri0olarak temizlenir ve önceki bir yenilemede yönetilenuid_*dizinleri (ör. kullanıcı başlatıcıları değiştirdikten sonra önceki ana sayfa başlatıcısı)0olarak sıfırlanır.
Şekil 1. Cgroup dilimleri arasında üç düzeyli koruma tabanı yetkilendirmesi.
MGLRU çekirdeklerinde neden memory.low yerine memory.min kullanılır?
Çok Nesilli LRU (MGLRU, Android 6.6 ve daha yeni çekirdeklerdeki varsayılan sayfa geri alma motoru) kapsamında, memory.low ve memory.min, mm/vmscan.c:shrink_one içinde farklı davranır:
memory.low(tek geçişli erteleme): Kullanımımemory.lowdeğerinin altında olan bir cgroup, memcg LRU'nun (MEMCG_LRU_TAIL) sonuna döndürülür ve tek bir geri alma geçişi için atlanır. Sürekli bellek baskısı altında bir sonraki geçişte çekirdek, cgroup'u tamamen geri alır ve birMEMCG_LOWetkinliği kaydeder. Anonim bir bellek canavarının fiziksel RAM'in %85'ine ulaştığı fiziksel cihaz stres testlerindememory.low, akıllı saatteSystemUIuygulamasının yaklaşık 45 MB'tan yaklaşık 5-10 MB'a düşmesini ve 16 GB'lık katlanabilir cihazdaaudioserveruygulamasının yaklaşık 14 MB'lık bir tabana karşı 15 MB'tan 2 MB'a düşmesini sağladı.memory.min(kesin koruma tabanı): Kullanımımemory.mindeğerinin altında olan bir cgroup, genel geri alma tarafından atlanır. Şekil 2'de gösterildiği gibi, aynı %85 RAM baskısı iş yükü altındamemory.min, her bir arka plan programının yalnızca en soğuk %10'luk kısmını atar veSystemUI,surfaceflingerveaudioserver'yi %90'lık tabanlarında tutar. Bu sırada sıfır anonim yeniden hata oluşur velmkdişlem sonlandırmalarında artış olmaz.
memory.min, değiştirdiği PinnerService mlock sabitleme korumasına uygun, fiziksel bir rezervasyon sağlar. Bu sayede, hangi etkin kod, yığın ve grafik sayfalarının kalıcı olacağını statik bir dosya listesi yerine çekirdek LRU seçer.
Şekil 2. Artan bellek baskısı altında arka plan işlemi çalışma kümesi saklama.
Başlatma öncesi ön ısıtma ve başlatma sonrası eşlenmemiş dosya önbelleğini geri alma
config_defaultPinnerServiceFiles uygulamasının kalıcı PinnerService mlock öğesini değiştirmek için iki başlatma zamanı davranışının koordine edilmesi gerekir:
- Tek seferlik arka planda başlatma ön ısıtması (
PinnerService): Sayfa önbelleğini ısıtmadanPinnerServicemlockişlemini atlamak,SystemUIbaşlatıldığında (OnBootPhase_550) yaklaşık 95 MB'lıkSystemUIAPK, ODEX ve VDEX disk okumalarını eşzamanlı başlatma yoluna kaydırarak başlatma işleminin tamamlanmasına 300 ila 450 ms ekler. Çekirdektekiforce_page_cache_ra, tek birMADV_WILLNEEDçağrısını bir önceden okuma penceresine (genellikle 128 KB ila 2 MB) sıkıştırdığı içinmadvise(MADV_WILLNEED)çağrısı yeterli değildir. Bunun yerine,SystemMemoryBudgetManager.shouldSkipDefaultSystemPinningetkin olduğundaPinnerService,onStartsırasında bir arka plan iş parçacığındaconfig_defaultPinnerServiceFilesiçindeki her dosyayı eşler, dosyayıOs.mlockile sayfa önbelleğine eşzamanlı olarak doldurur ve hemenOs.munlock,munmapveclose'yi çağırır. Bu sayede, hızlı başlatma zamanlaması korunurken kalıcı olarak kilitli bayt sayısı sıfırda kalır. Böylece, sıfırdan başlatma sayfaları daha sonra kaldırılabilir. - Eşlenmemiş dosya önbelleğini hariç tutma ve başlatma paketi tarama önbelleğini geri alma:
Başlatma sırasında
PackageManagerService, yüklü APK'ları tarar vesystem_servercgroup'a yüklenen 1, 5 ila 2, 5 GB'lık soğuk eşlenmemiş dosya sayfası önbelleği bırakır.Diğer korumalı işlemler de (ör.XR cihazlarda 3D öğe dosyalarını okuyanSystemUI) tek seferlik okumalardan eşlenmemiş dosya önbelleğini koruyabilir.memory.minhesaplamasına dahil edilirse bu soğuk önbellek, %10'luk global RAM sınırını doldurabilir vesurfaceflinger,SystemUIveaudioserverkoruma tabanlarını orantılı olarak ölçeklendirebilir. Sınır yetersizliğini önlemek içinSystemMemoryBudgetManager, her korumalı işlem içinmemory.statdeğerini okur, eşlenmemiş dosya önbelleğinimax(0, file - shmem - file_mapped)olarak hesaplar ve Şekil 3'te gösterildiği gibi %90'lık alt sınırı hesaplamadan önce bu eşlenmemiş önbelleğimemory.currentdeğerinden çıkarır. Ayrıca,PHASE_BOOT_COMPLETEDişleminden 10 saniye sonra yönetici, anonim yığınları değiştirmeden veya eşlenen DEX ve kod sayfalarını çıkarmadan soğuk paket tarama önbelleğini proaktif olarak çıkarmak için Linux 6.2 ve daha yeni çekirdeklerdesystem_serveröğesininmemory.reclaimdüğümüne<unmapped_file> swappiness=0öğesini tek seferlik yazar.swappiness=0'yiEINVALile reddeden eski çekirdeklerde (ör.android14-6.1) yönetici, başlatma sırasında anonim yığını değiştirecek niteliksiz bir geri alma yazma işlemine geri dönmek yerinememory.reclaimyazma işlemini atlar.
Şekil 3. Önyüklemeden sonra koruma tabanı yakınsaması ve önbellek geri kazanımı.
Çekirdek gereksinimleri ve cihaz yapılandırması yer paylaşımları
SystemMemoryBudgetManager, memory.min değerini iç içe yerleştirilmiş cgroup'lara yaymak için Linux çekirdeğindeki mem_cgroup_calculate_protection özelliğini kullanır. Android ortak çekirdekleri android15-6.6 ve android16-6.12, tam MGLRU iç içe koruma desteğiyle birlikte sunulur. MGLRU etkinleştirilmiş android14-6.1 çalıştıran cihazlar, boş ara dilim ve UID cgroup'larının korumayı yaprak işlem cgroup'larına yayması için mm/vmscan.c ve mm/memcontrol.c içinde üç adet yukarı akış geri bağlantı noktası gerektirir:
30d77b7eef01(mm/mglru: fix ineffective protection calculation)8aa420617918(mm/mglru: respect min_ttl_ms with memcgs)adb8213014b2(mm: memcg: fix stale protection of reclaim target memcg)
OEM'ler, aşağıdaki özellik bayrağını ve çerçeve kaynak yer paylaşımlarını kullanarak SystemMemoryBudgetManager özelliğini etkinleştirebilir, özelleştirebilir veya devre dışı bırakabilir:
com.android.server.am.system_process_memory_budgets(aconfig özellik bayrağı):SystemMemoryBudgetManagerözelliğini etkinleştirir ve varsayılanPinnerServicesistem ve Homemlocksabitleme işlemini atlar (ilk Android 17 sürümünde varsayılan olarak devre dışıdır).config_systemMemoryBudgetLowKb(tam sayı, KB):0(varsayılan), tümmemory.minalt sınırlarının toplamını toplam fiziksel RAM'in %10'u ile sınırlandırır. Pozitif bir değer, KB cinsinden açık bir sınır belirler ve negatif bir değer, cihazdaSystemMemoryBudgetManagerözelliğini devre dışı bırakır (eskiPinnerServicestatikmlocksabitlemeyi korur).config_systemMemoryBudgetHighKb(tam sayı, KB):0(varsayılan),/sys/fs/cgroup/system/memory.highdeğerinimaxolarak bırakır. Pozitif bir değer, üst dilimmemory.hightavanını belirler (taban sınırından büyük veya ona eşit olmalıdır).config_systemMemoryBudgetAdditionalSystemProcesses(dize dizisi): Varsayılan altı sistem arka plan işlemine ek olarak %90memory.mintabanlarıyla korunacak,/sys/fs/cgroup/systemiçinde ek gecikme açısından kritik yerel sistem veya tedarikçi arka plan işlemi adlarını (/proc/<pid>/commile veya10000altındaki sistem ve tedarikçi UID'leri için/proc/<pid>/cmdlineiçindekiargv[0]öğesinin temel adıyla eşleştirilir) listeler.init.rciçindememory.mindeğerini ayarlamak yerine bu yer paylaşımını kullanın. ÇünküSystemMemoryBudgetManager,uid_<uid>/memory.mindeğerini yönetilen yaprak işlemlerinin toplamı olarak yeniden hesaplar ve her yenilemede yönetilmeyenuid_*düğümlerini temizler. Örneğin, bir XR cihazı, konumsal izleme ve kamera HAL daemon'larını (android.hardware.perceptionhostveauracamerahal) koruyabilir. Android Masaüstü cihazı ise ses ve USB kamera HAL daemon'larını (dras.core.audioveandroid.hardware.camera.provider-usb-service.android-desktop) koruyabilir:<!-- XR device overlay --> <string-array translatable="false" name="config_systemMemoryBudgetAdditionalSystemProcesses"> <item>android.hardware.perceptionhost</item> <item>auracamerahal</item> </string-array> <!-- Android Desktop device overlay --> <string-array translatable="false" name="config_systemMemoryBudgetAdditionalSystemProcesses"> <item>dras.core.audio</item> <item>android.hardware.camera.provider-usb-service.android-desktop</item> </string-array>config_systemUi(dize): Platform SystemUI uygulamasının paket adı,MATCH_SYSTEM_ONLYile çözümlenir.
Bir cihazdaki etkin SystemMemoryBudgetManager katlarını ve cgroup düğümlerini incelemek için şunu çalıştırın:
# Inspect policy state, resolved PIDs, and applied floors adb shell dumpsys system_server_dumper --name SystemMemoryBudgetManager adb shell dumpsys meminfo | sed -n '/System Memory Budgets/,$p'# Inspect raw cgroup v2 memory.min nodes across the system and apps slices adb shell head -n 1 \ /sys/fs/cgroup/system/memory.min \ /sys/fs/cgroup/system/uid_*/memory.min \ /sys/fs/cgroup/system/uid_*/pid_*/memory.min \ /sys/fs/cgroup/apps/memory.min \ /sys/fs/cgroup/apps/uid_*/memory.min \ /sys/fs/cgroup/apps/uid_*/pid_*/memory.min
Bellek bütçeleriyle bağlı kalıcı ve arka plan sistem uygulamaları
SystemMemoryBudgetManager, memory.min tabanlarını kullanarak etkileşimli daemon'ları geri alınmaya karşı korur. Diğer birçok sistem uygulaması ve ayrıcalıklı platform hizmeti ise arka planda uzun süre PERSISTENT işlemleri, bağlı ön plan hizmetleri veya sık sorgulanan içerik sağlayıcılar olarak çalışır.
Açık bellek tavanları olmadan bu işlemler, çok gigabaytlık Bellek Sınırlayıcı sınırlarına (ör. görünür uygulamalar için 4 GB ila 10 GB ve arka plan uygulamaları için 2 GB ila 5 GB) ulaşana veya genel bellek baskısı sistem genelinde kswapd ve düşük bellek sonlandırıcı (lmkd) etkinliğini tetikleyene kadar kısıtlanmaz.
Kısıtlama uygulanmadığında arka plan sistem işlemleri genellikle etkin çalışma gruplarının parçası olmayan büyük miktarda soğuk bellek biriktirir:
- Sınırsız dosya sayfası önbelleği: Medya dizine ekleyen, veritabanlarında arama yapan veya takvim ve sağlayıcı tablolarını senkronize eden hizmetler (ör.
AppSearch,MediaProviderveCalendarProvider), diskteki büyük dosyaları eşler veya bu dosyalar üzerinden akış gerçekleştirir. cgroupmemory.highüst sınırı olmadan, tek seferlik okumalardan elde edilen temiz dosya destekli sayfalar, süresiz olarak işlem cgroup'una yüklenir ve yüzlerce megabayt fiziksel RAM tüketir. - Ani artış sonrası anonim yığın saklama:
BluetoothSes ve BLE keşif ani artışları,NetworkStackgiriş portalı TLS doğrulaması veya arka plana geçiş yapan kullanıcı arayüzü yardımcıları gibi geçici etkinlik artışları yaşayan hizmetler, ani artış tamamlandıktan uzun süre sonra soğuk anonim yığın sayfalarını saklayabilir.
Sistem uygulamalarına kalibre edilmiş <memory-budget> beyanları (memory.high esnek sınırlar, genellikle 30 MB ila 190 MB) uygulamanın iki temel avantajı vardır:
- Proaktif, yerelleştirilmiş sayfa geri alma: Bir sistem işlemi, yapılandırılmış
memory.highbütçesini aştığında Linux çekirdeği, sayfa geri alma işlemini özellikle bu cgroup'a yönlendirir. Önce soğuk dosya destekli sayfaları çıkarır ve etkin olmayan anonim sayfaları, global cihaz bellek baskısını beklemeden ZRAM'e sıkıştırır. - Ön planda çalışan uygulamalar ve önbelleğe alınmış uygulama havuzu için daha fazla RAM: Her zaman açık sistem hizmetlerinde soğuk dosya önbelleklerinin sınırlandırılması, cihaz genelinde onlarca ila yüzlerce megabayt fiziksel RAM'i geri kazanarak kullanıcı arayüzü takılmalarını azaltır, kamera başlatma baskısını düşürür ve daha fazla kullanıcı uygulamasını önbelleğe alınmış durumda tutar.
Sistem uygulaması bellek bütçelerini yapılandırma
Sistem uygulamaları, genel uygulamalarla aynı <memory-budget> manifest söz dizimini, işlem durumu basamaklamasını, ekran yoğunluğu ölçeklendirmesini ve son eşleşen yan tümce çözümleme kuralını kullanır. Özelliklerin tam listesi için XML özellik referansı'na bakın.
OEM'ler, <memory-budget> öğelerini doğrudan bir sistem uygulamasının AndroidManifest.xml öğesinde tanımlayabilir veya Android.bp içindeki additional_manifests özelliğini kullanarak ayrı bir XML dosyasından birleştirebilir. AOSP, referans sistem uygulaması bütçelerini kural olarak bağımsız *-budget.xml dosyalarında (temel platform paketleri için frameworks/base/core/memory_budgets/ içinde veya packages/modules/NetworkStack/memory_budgets/, packages/modules/AppSearch/apk/ ve packages/services/Telephony/ gibi bağımsız modüllerle birlikte) depolar ve bunları additional_manifests ile ekler:
android_app {
name: "TeleService",
manifest: "AndroidManifest.xml",
additional_manifests: ["Telephony-budget.xml"],
// ...
}
Paket düzeyinde (UID) ve işlem düzeyinde (PID) kapsam belirleme
Paket düzeyinde temel bütçe (<application>) veya çoklu işlem bütçesi (<processes><process>) bildirmeniz, çekirdeğin memory.high'yi UID cgroup düzeyinde (/sys/fs/cgroup/uid_<uid>/memory.high) mi yoksa PID başına cgroup düzeyinde (/sys/fs/cgroup/uid_<uid>/pid_<pid>/memory.high) mi uygulayacağını belirler. Bu durum Şekil 4'te gösterilmektedir:
- Paket düzeyinde (
<application>) bütçe: APK, kendi özel UID'si altında tek bir işlem çalıştırdığında (ör.Bluetooth,Nfc,NetworkStack,CalendarProvider,TraceurveyaAppSearch) kullanın. - İşlem düzeyinde (
<processes><process>) bütçe: APK, diğer sistem paketleriyleandroid:sharedUserId(ör. UID1001ileandroid.uid.phoneveya UID1000ileandroid.uid.system) paylaştığında bu bütçeyi kullanın. Böylece, bu UID'yi paylaşan diğer işlemler birlikte kısıtlanmaz. Tek bir APK, farklı bellek rollerine sahip birden fazla işlem (ör. arka planMediaProviderdaemon'u ve:PhotoPickerkullanıcı arayüzü alt işlemi) çalıştırdığında da bu bütçeyi kullanabilirsiniz.
Şekil 4. UID düzeyinde ve PID düzeyinde bellek tavanları.
Aşağıdaki örnekte, RAM katmanlı bütçeleri varsayılan MediaProvider işlemine (<process>) ve ekran ölçekli bütçeyi :PhotoPicker kullanıcı arayüzü işlemine göre kapsamlandıran MediaProvider-budget.xml gösterilmektedir. Her android:maxDeviceRamMb özelliği, toplam fiziksel RAM'i (MemTotal) belirtilen MB eşiğinde veya altında olan cihazlarla eşleşir (veya atlandığında herhangi bir RAM kapasitesi için geçerli olur). Maddeler, kısıtlanmamış varsayılandan en küçük maxDeviceRamMb eşiğine doğru sıralanır. Böylece son eşleşen madde çözüm kuralı, geçerli en dar katmanı seçer:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.providers.media.module">
<uses-sdk android:targetSdkVersion="10000" />
<application>
<processes>
<process>
<memory-budget
android:maxMb="85" />
<memory-budget
android:maxMb="75"
android:maxDeviceRamMb="12288" />
<memory-budget
android:maxMb="60"
android:maxDeviceRamMb="8192" />
</process>
<process android:process=":PhotoPicker">
<memory-budget
android:maxMb="85"
android:additionalBytesPerDisplayPixel="25" />
</process>
</processes>
</application>
</manifest>
Bir bütçe manifestinde <processes> beyan ettiğinizde <process> girişlerini yalnızca <memory-budget> beyan eden işlemler için listeleyin (varsayılan uygulama işlemi <application> üzerinde özel bir android:process adı beyan ederse adsız bir <process /> etiketi kullanmak yerine bu adı <process android:process="..."> öğesinde belirtin). APK derleme sırasında aapt2, birleştirilmiş manifest dosyasındaki bileşenler tarafından beyan edilen bütçesiz işlemler için <process> girişlerini otomatik olarak ekler ve Android 17 ile uyumluluk için gerektiğinde <application> altına kapsayıcı bir <memory-budget android:maxMb="1000000" /> ekler. Böylece işlem başına bütçeler hedef işlemlerinden ayrı kalır.
AOSP referans bütçeleri Google Pixel cihazlarda nasıl kalibre edildi?
AOSP'deki referans sistem uygulaması bellek bütçeleri, 6 GB ila 16 GB fiziksel RAM (6 GB, 8 GB, 12 GB ve 16 GB telefonlar, katlanabilir cihazlar ve tabletler dahil) ve yaklaşık 1,2 MP (720×1600) ila yaklaşık 4,5 MP (2076×2152) ekran çözünürlüklerine sahip Google Pixel cihazlarda kalibre edilmiştir.
Kalibrasyon, iki tamamlayıcı veri kaynağını birleştirdi: filo genelinde cgroup v2 alan telemetrisi ve kritik kullanıcı yolculukları (CUJ'ler) genelinde kontrollü fiziksel cihaz memory.high taramaları.
Filo genelinde cgroup v2 telemetri analizi
Cihaz filosundan düzenli olarak cgroup v2 anlık görüntüleri toplandı ve fiziksel RAM katmanına (≤8 GB, 12 GB ve ≥16 GB) ve işlem durumu grubuna (foreground, perceptible, background ve cached) göre dilimlere ayrıldı. İstatistiksel analizde altı ilke temel alındı:
memory.current'i çalışma kümesi ve geri kazanılabilir dosya önbelleği olarak ayırma:memory.high, yerleşik cgroup ücretini (memory.current) yönettiği için her anlık görüntü,memory.statkullanılarak anonim yığın (anon), takas edilen anonim sayfalar (swap) ve dosya destekli sayfa önbelleği (file) olarak ayrıldı (Şekil 5'te gösterildiği gibi). Toplam sıkıştırılamayan anonim talep (P99'daanon + swap), bütçe için minimum çalışma kümesi tabanını belirler. Böylece işlem, ZRAM tükenme riskiyle karşı karşıya kalmaz.memory.currentP99 ileanon + swapP99 arasındaki büyük fark ise önbelleğin eşlenmemiş ve soğuk olması koşuluylamemory.hightarafından geri alınabilecek dosya sayfası önbelleğini gösterir.memory.hightarafından geri alınamayan belleği hesaba katın: Tüm dosya ve paylaşılan bellekler soğuk önbellek değildir. Kilitli sayfalar (memory.statiçindeunevictable, örneğinmlockile kilitli paylaşılan bellek veya ana makine işlemleri uygulamanın cgroup'una yüklenen bir sanal makinenin kilitli misafir RAM'i), bütçenin altında kesin bir alt sınır belirler ve eşlenen sayfalar (file_mapped) genellikle etkin çalışma grubunun bir parçasıdır. Dosya belleğini geri alınabilir olarak değerlendirmeden önceunevictable,shmemvefile_mappeddeğerlerini kontrol edin. Örneğin,AppSearchbelleğin yaklaşık 100 MB'ı kilitli ve çıkarılamaz. Bu nedenle, bütçesi bu alt sınırı ve etkin ana makine çalışma grubunu kapsar. Ayrıca kilitli bölgenin büyümesi için de yer vardır.- Boşta durumundaki seyreltmeyi filtreleme: İçerik sağlayıcılar (
CalendarProvider) ve isteğe bağlı geliştirici araçları (Traceur), alan anlık görüntülerinin %70 ila %99,9'unu yaklaşık 1 MB ila 3 MB boşta geçirir. Tüm anlık görüntülerde ham yüzdelik dilimlerin hesaplanması, P95 ve P99 tahminlerini ciddi şekilde azaltır. Bunun yerine, yüzdelik dilimler ve güven aralıkları, seyreltilmemiş etkin anlık görüntüler üzerinden hesaplandı (CACHEDanlık görüntü ve boşta referans anlık görüntüler filtrelendi). - Cihaz kümesine göre gruplandırılmış güven aralıkları kullanın: Tek bir cihaz zaman içinde birçok periyodik anlık görüntüye katkıda bulunduğundan, anlık görüntüleri bağımsız örnekler olarak ele almak kuyruk belirsizliğini olduğundan az gösterir. Tüm P95 ve P99 çalışma kümesi tahminleri, cihaz kümesine göre %95 güven aralıkları (etkin örneklem boyutu olarak farklı cihaz sayısı
N_devkullanılarak) kullanılarak değerlendirildi. memory.peakile geçici artışları hesaba katın: Periyodik örnekleme, kısa süreli ve yüksek tahsisli artışları (ör.NetworkStackgiriş portalı TLS doğrulaması ve eşzamanlı DNS probları veyaBluetoothA2DP ve BLE başlatma) kaçırabilir. Anlık yoğunluk gösteren hizmetlerde bütçeler, RAM katmanları genelinde kullanım ömrü boyunca çekirdekmemory.peakyüksek kullanım seviyelerinin %90 ila %95'ini kapsayacak şekilde boyutlandırıldı.- RAM katmanının cihaz neslini değil, RAM'i yansıttığını doğrulayın: Yeni cihazlar genellikle daha fazla RAM'e ve daha fazla özelliğe sahiptir. Bu nedenle, RAM katmanıyla birlikte büyüyen bir çalışma grubu aslında özelliklerle birlikte büyüyor olabilir.
maxDeviceRamMbkatmanı eklemeden önce verileri cihaz modeline göre dilimleyin. Örneğin,com.android.phone, aynı neslin 12 GB ve 16 GB telefonlarında aynı P99anon + swap'a (~85-90 MB) ulaşırken daha eski bir 12 GB katlanabilir telefon 40 MB kullanır. Bu nedenle, bütçesi RAM katmanı olmayan tek bir değer kullanır. Böylece, daha yeni telefon özelliklerini sunan daha düşük RAM'li bir cihazın bütçesi yetersiz kalmaz.
Şekil 5. Çalışma kümesi ile geri kazanılabilir dosya önbelleği karşılaştırması.
Fiziksel cihaz CUJ ve ekran ölçeklendirme taramaları
Telemetriden türetilen bütçeleri doğrulamak ve ekrana orantılı bütçeleri (ör. :PhotoPicker) ve duruma özgü arka plan bütçelerini (ör. Traceur) kalibre etmek için 6 GB ila 16 GB RAM'e sahip fiziksel cihazlarda canlı memory.high taramaları yapıldı:
- Sıfır yeniden hata dizini bulma: Uçtan uca CUJ'leri (ör. hızlı fotoğraf ızgarası kaydırma, albümde gezinme, tam ekran yüksek çözünürlüklü fotoğraf ve video önizleme kaydırma, iz kaydetme ve kaydetme) çalıştırırken cgroup
memory.statsayaçları (workingset_refault_anon,workingset_refault_file,pgscanvepgsteal) ilememory.events(high) ölçülürkenmemory.highazaltıldı. Şekil 6'da gösterildiği gibi, optimum bütçe sıfır yeniden hata dizininin hemen üzerinde yer alır. Sıfır yeniden hata diz, çekirdeğin etkin çalışma kümesi thrashing'ini (workingset_refault == 0) tetiklemeden soğuk tek seferlik dosya önbelleğini (pgsteal > 0) geri aldığı eşiktir. - Farklı çözünürlüklerde ekran pikseli ölçeklendirmesini doğrulama:
Yaklaşık 1,2 MP (720×1600) ile yaklaşık 4,5 MP (2076×2152 katlanmamış
iç ekran) arasında değişen dört fiziksel ve emüle edilmiş ekran çözünürlüğünde yapılan testler
:PhotoPicker, etkin Glide ve ViewPager2 bitmap çalışma setinin ekran piksel sayısıyla doğrusal olarak ölçeklendiğini doğruladı. Görüntüleme dışı referans da cihaza göre değişir: Neredeyse aynı piksel sayısında, sıfır yeniden hata diz noktası, 16 GB katlanabilir cihazın dış ekranında yaklaşık 140 MB, 6 GB telefonda ise 110 ila 125 MB arasındaydı. 85 MB'lık bir taban değer ve ekran pikseli başına 25 bayt (android:maxMb="85"veandroid:additionalBytesPerDisplayPixel="25"), test edilen her ekranda ölçülen büküm noktasının üzerinde kalır (HD+'da yaklaşık 110 MB, FHD+'da yaklaşık 145 MB ve katlanabilir ekranlarda yaklaşık 190 MB). - Arka plan durumlarında ART çöp toplama işlemini doğrulama: cgroup v2'de, Zygote tarafından paylaşılan
boot.artve çerçeve görüntü sayfaları, Zygote'un cgroup'una bağlı kalır ve ART eşzamanlı işaretleme-sıkıştırma (CMC) çöp toplama işlemi sırasında bağışık alan olarak değerlendirilir. Stres testi, bir sistem kullanıcı arayüzü uygulamasıbackgrounddurumuna geçtiğindememory.highdeğerini sıkılaştırmanın (ör.Traceurüzerinde 30 MB'a) GC çöp toplama veya takas etkinliğine neden olmadan özel yığın ve sayfa önbelleğini temiz bir şekilde sınırladığını doğruladı.
Şekil 6. CUJ sırasında sıfır yeniden hata dizini bulma.
AOSP referans sistem uygulaması bütçelerinin özeti
Aşağıdaki tabloda, AOSP'deki kalibre edilmiş referans bütçeler RAM katmanlarına ve işlem durumlarına göre özetlenmiştir:
| Sistem paketi veya işlemi | Kapsam | ≤8 GB RAM | 12 GB RAM | ≥16 GB RAM | Birincil kalibrasyon sürücüsü |
|---|---|---|---|---|---|
com.android.bluetooth |
UID (<application>) |
80 MB | 95 MB | 110 MB | P90 kullanım ömrü memory.peak patlamalarını (~75 ila 110 MB) ve >2 kat P99 etkin memory.current'yi kapsar. |
com.android.nfc |
UID (<application>) |
50 MB | 60 MB | 60 MB | Etkin ana kart emülasyonu P99 (yaklaşık 50 MB'a kadar) ve P90 ila P95 memory.peak değerlerini kapsar ve soğuk dosya önbelleğini kırpar. |
com.android.providers.calendar |
UID (<application>) |
70 MB varsayılan (ön plan) 50 MB perceptible ve background |
Etkin çalışma kümesi, RAM katmanları arasında değişmez. Arka plan bütçesi, senkronizasyonlar sırasında SQLite sayfa önbelleğini kırparken hatırlatıcı alarmlar için anonim boşluk bırakır. | ||
com.android.traceur |
UID (<application>) |
85 MB varsayılan (ön plan ve algılanabilir) 30 MB background |
Etkin izleme kaydı ve dışa aktarma (TraceService) sırasında 85 MB'lık tam boşluk korunurken boşta ve yayın durumunda 30 MB ile sınırlandırılır. |
||
com.android.providers.media.module (ana) |
PID (<process>) |
60 MB | 75 MB | 85 MB | Soğuk SQLite ve küçük resim dosyası önbelleğini geri alırken P99 anon + swap üzerinde yaklaşık 10 ila 30 MB boşluk sağlar. |
com.android.providers.media.module:PhotoPicker |
PID (<process>) |
85 MB + piksel başına 25 bayt (HD+'ta yaklaşık 110 MB, FHD+'ta yaklaşık 145 MB, yaklaşık 4,5 MP katlanabilir cihazda yaklaşık 190 MB) |
Glide bitmap çalışma kümesi dizine uyacak şekilde, ekran piksel sayısıyla (additionalBytesPerDisplayPixel="25") orantılı olarak ölçeklendirilir. |
||
com.android.networkstack |
UID (<application>) |
65 MB | 70 MB | 85 MB | Giriş portalı TLS, DNS ve DHCP artışlarını kapsayacak şekilde P95 kullanım ömrü memory.peak olarak boyutlandırılmış, ağırlıklı olarak anonim bellek. |
com.android.appsearch.apk |
UID (<application>) |
130 MB | Kilitli bölgenin büyümesi için yer bırakarak yaklaşık 100 MB kilitli, çıkarılamayan bellek ve yaklaşık 5 MB etkin ana makine çalışma kümesini kapsar. Soğuk sayfa önbelleği (P99'da yaklaşık 330 MB'a kadar) geri alınırken ≥125 MB'ta sıfır yeniden hata ölçüldü. | ||
com.android.phone (TeleService) |
PID (<process>) |
120 MB | Paylaşılan UID 1001'de PID başına kapsamlı. Çalışma kümesi, RAM yerine cihaz neslini izler. Bu nedenle, tek bir bütçe, model başına en yüksek P99'un yaklaşık 30 MB üzerindedir anon + swap. |
||
OEM'ler kendi cihazları için sistem uygulaması bütçelerini nasıl yeniden kalibre edebilir?
Sistem uygulamalarını özelleştiren (ör. tedarikçi firma Bluetooth profilleri, özel telefon uzantıları veya OEM medya dizinleyicileri ekleyen) ya da ek önceden yüklenmiş sistem hizmetleri sunan OEM'ler, mevcut bütçeleri yeniden kalibre edebilir veya donanım portföyleri için yeni *-budget.xml dosyaları yazabilir.
Etkin cgroup v2 bellek profillerini toplama
Her hedef sistem işlemi için, temsili iş yükleri ve RAM katmanları genelinde /sys/fs/cgroup/uid_<uid>/pid_<pid>/ altındaki cgroup v2 bellek düğümlerini okuyun:
memory.current: cgroup'tan alınan mevcut yerleşik bellek (Zygote tarafından paylaşılan sayfalar hariç)memory.peak: İşlem başlangıcından bu yana ulaşılan en yüksekmemory.currentdeğerimemory.swap.current: ZRAM'de mevcut sıkıştırılmış takas kullanımımemory.stat:anon,file,pgscan,pgsteal,workingset_refault_anonveworkingset_refault_filedökümümemory.events:highihlalin kümülatif sayısı (memory.highkısıtlama ve geri alma etkinlikleri)
Dogfood veya saha cihazlarından telemetri verilerini toplarken etkin işlem durumlarını (TOP, FOREGROUND_SERVICE, etkin bağlamalar ve etkin senkronizasyonlar) boşta CACHED veya boşta PERSISTENT durumlarından ayırın. Böylece boşta anlık görüntüler, P95 ve P99 çalışma kümesi hesaplamalarınızı aşağı doğru saptırmaz.
Sıkıştırılamayan yığınları geri kazanılabilir dosya önbelleğinden ayırma
anon + swap için 99. yüzdelik dilimi, memory.current için 99. yüzdelik dilimle karşılaştırın:
- Dosya önbelleğinin baskın olduğu hizmetler (
file≫anon, örneğin veritabanı sağlayıcılar, arama dizini oluşturucular ve günlük arka plan programları): P99anon + swapüzerinde rahat bir boşluk (genellikle 1, 5 kat ila 4 kat) ve etkin dosya sayfaları için bir çalışma penceresi sağlamak üzereandroid:maxMbdeğerini ayarlayın. Bu yapılandırma, çekirdeğin anonim yığına dokunmadan soğuk eşlenmemiş dosya sayfalarını sürekli olarak çıkarmasına olanak tanır.unevictableveyafile_mappedbüyükse (kilitli bellek veya bellekle eşlenen veritabanlarında olduğu gibi) bu ayak izini de çalışma kümesi olarak sayın. - Anonim yığın ağırlıklı veya ani artış gösteren hizmetler (
anon,memory.currentdeğerinin çoğunu oluşturur; örneğin, ağ veya bağlantı yığınları):memory.peakdeğerinin P90 ila P95'ini kapsayacak şekildeandroid:maxMbboyutunu ayarlayın. Böylece geçici ani artışlar, gecikmeye duyarlı mesaj dizilerinde eşzamanlı ZRAM takasını tetiklemez. - Ekran yoğun kullanıcı arayüzü işlemleri (seçiciler, galeriler veya sistem kullanıcı arayüzü yardımcıları gibi): Kullanıcı arayüzü olmayan temel ayak izini ve en düşük ve en yüksek çözünürlüklü ekranlarınızda megapiksel başına artımlı bitmap ayak izini ölçün ve bütçeyi
android:maxMbartıandroid:additionalBytesPerDisplayPixelkullanarak ifade edin.
Fiziksel cihazlarda memory.high değerini temizleme
Derlemeye yeni bir bütçe ayırmadan önce otomatik CUJ testlerinizi çalıştırırken aday sınırları test etmek için am memory-limiter manual komutunu kullanın (veya doğrudan kullanıcı hata ayıklama derlemesinde işlemin memory.high cgroup düğümüne yazın):
# Override memory.high for a specific PID to 60 MB during a CUJ test
adb shell am memory-limiter manual <PID> 60MBCUJ'den önce ve sonra memory.stat ve memory.events değerlerini izleyin:
- Bütçe çok düşük:
workingset_refault_anonveyaworkingset_refault_file, CUJ sırasında keskin bir şekilde artıyor,memory.swap.current, etkin ön plan çalışması sırasında sürekli olarak artıyor veya CUJ karesi ya da Binder gecikmesi geriliyor. Bütçeyi varsayılan eşiğin üzerine çıkarın. - Bütçe çok yüksek: Yoğun dosya akışı veya dizine ekleme iş yüklerinden sonra bile
memory.events:high,0olarak kalır vememory.statiçindekifile, soğuk sayfalarla sınırsız bir şekilde büyür. Bütçeyi etkin çalışma kümesine göre daraltın. - Bütçe iyi kalibre edilmiş: Kararlı durum
memory.current, normal çalışma sırasındamemory.highdeğerinin altında kalır. Yoğun dosya veya önbellek patlamaları sırasındapgsteal, soğuk dosya sayfalarını geri kazanırkenworkingset_refault_anonsıfıra yakın kalır ve CUJ gecikmesi değişmez.