Di Android 17 dan yang lebih tinggi, platform mengatur memori proses sistem menggunakan dua mekanisme cgroup v2 Linux pelengkap yang berfungsi bersama Pembatas Memori aplikasi umum:
- Batas minimum perlindungan daemon sistem (
SystemMemoryBudgetManagerdenganmemory.min): Pemesananmemory.mincgroup v2 yang dapat menyesuaikan sendiri (ditetapkan ke 90% dari set kerja residen yang diselesaikan setiap daemon dan dibatasi secara global sebesar 10% dari total RAM fisik) melindungi daemon interaktif penting dan proses shell (system_server,surfaceflinger, HALcomposergrafis,audioserver,cameraserver,netd,SystemUI, dan peluncur Layar utama) di bawah tekanan memori, menggantikan penyematan filePinnerServicemlockstatis. - Batas memori aplikasi sistem (
<memory-budget>denganmemory.high): Batas lunakmemory.highcgroup v2 yang dikalibrasi workload (biasanya 30 MB hingga 190 MB) yang dideklarasikan dalam file manifes untuk aplikasi sistem persisten dan latar belakang (Bluetooth,Nfc,CalendarProvider,Traceur,MediaProvider,:PhotoPicker,NetworkStack,AppSearch, danTeleService) secara proaktif mengklaim kembali cache halaman file dingin dan heap anonim pasca-burst sebelum terjadi tekanan memori global.
Tabel berikut membandingkan kedua mekanisme tersebut:
| Dimensi | Batas perlindungan daemon sistem | Batas memori aplikasi sistem |
|---|---|---|
| Layanan platform | SystemMemoryBudgetManager |
MemoryLimiter |
| Kontrol cgroup v2 | memory.min hard protection floor |
Batas atas klaim kembali fleksibel memory.high |
| Proses target | Daemon interaktif yang sangat sensitif terhadap latensi dan UI shell (system_server, surfaceflinger, HAL composer, audioserver, cameraserver, netd, SystemUI, dan aplikasi Home) |
Aplikasi sistem persisten dan headless, penyedia konten, serta layanan latar belakang (seperti Bluetooth, Nfc, MediaProvider, NetworkStack, AppSearch, dan TeleService) |
| Model penentuan ukuran | Penyesuaian mandiri saat runtime (90% set kerja yang ditetapkan, dibatasi secara global sebesar 10% dari total RAM) tanpa tabel penyesuaian per perangkat | Atribut XML manifes <memory-budget> deklaratif yang dikalibrasi berdasarkan tingkat RAM, status proses, dan jumlah piksel layar |
| Manfaat utama | Mencegah jank UI interaktif dan penghentian aktivasi saat memori penuh, sekaligus mengganti daftar file PinnerService mlock statis |
Terus menghapus cache file satu kali yang tidak aktif dan heap pasca-burst untuk menyisakan lebih banyak RAM fisik bagi aplikasi latar depan dan aplikasi yang di-cache |
Untuk mengetahui informasi selengkapnya tentang sintaksis <memory-budget>, atribut XML, API runtime, dan pencatatan memori OS, lihat Menetapkan anggaran memori aplikasi dan Memahami dan memecahkan masalah memori Android.
Melindungi daemon interaktif penting dengan SystemMemoryBudgetManager
SystemMemoryBudgetManager mempertahankan proses yang berada langsung di jalur interaktif pengguna di RAM fisik selama tekanan memori. Daripada
menyematkan daftar statis file APK, ODEX, dan VDEX ke dalam memori dengan
mlock (seperti yang dilakukan PinnerService untuk config_defaultPinnerServiceFiles dan
config_pinnerHomePinBytes), SystemMemoryBudgetManager menetapkan batas minimum memory.min cgroup
v2 dinamis ke proses berikut:
- Slice sistem inti (
/sys/fs/cgroup/system):system_server,surfaceflinger, HALcomposergrafis,audioserver,cameraserver, dannetd, serta daemon vendor atau sistem native khusus faktor bentuk yang tercantum dalamconfig_systemMemoryBudgetAdditionalSystemProcesses(misalnya,android.hardware.perceptionhostdanauracamerahaldi perangkat XR). - Slice aplikasi interaktif (
/sys/fs/cgroup/apps): Proses utama paket SystemUI yang dikonfigurasi (config_systemUi) dan proses utama pemegang peran Beranda pengguna saat ini.
Melindungi pemegang peran Beranda bersama config_systemUi akan memastikan cakupan
di semua faktor bentuk. Pada faktor bentuk tempat config_systemUi adalah
paket kompatibilitas ringan (seperti Wear OS, tempat tampilan jam,
notifikasi, dan kartu berjalan di dalam aplikasi Home), shell yang ditampilkan kepada pengguna masih
menerima perlindungan set kerja penuh. Jika intent Home di-resolve ke
paket config_systemUi, proses akan dilindungi sekali. Hanya proses utama
setiap paket (processName == packageName) yang menerima batas perlindungan, sehingga
subproses tambahan (seperti :screenshot) tidak menggunakan anggaran perlindungan.
Kebijakan penyesuaian mandiri dan delegasi cgroup tiga tingkat
Karena set kerja daemon interaktif sangat bervariasi di berbagai faktor bentuk
dan kapasitas RAM (misalnya, SystemUI menggunakan sekitar 45 MB di
smartwatch, 60 MB di ponsel 6 GB, dan 180 MB di ponsel
16 GB), tabel pencarian statis per perangkat menjadi rentan. Sebagai gantinya,
SystemMemoryBudgetManager memperoleh batas bawah langsung dari jejak residen setiap proses
menggunakan tiga konstanta:
| Parameter kebijakan | Nilai default | Perilaku |
|---|---|---|
| Harga minimum per proses | 90% dari memory.current yang diselesaikan dikurangi cache file yang tidak dipetakan |
Melindungi heap anonim, slab, dan kode yang dipetakan panas sambil membiarkan 10% ekor terdingin dapat diklaim kembali sehingga halaman yang benar-benar dingin masih dapat dikeluarkan. Cache file yang tidak dipetakan (max(0, file - shmem - file_mapped) dari memory.stat) dikurangi sebelum menerapkan rasio 90% sehingga cache pemindaian paket booting atau pembacaan aset satu kali tidak meningkatkan batas minimum. |
| Batas RAM global | 10% dari total RAM (config_systemMemoryBudgetLowKb) |
Cocok dengan guardrail PinnerService config_pinnerMaxPinnedMemoryPercentage. Jika jumlah harga minimum 90% melebihi 10% dari MemTotal, setiap harga minimum akan diperkecil skalanya secara proporsional dengan faktor yang sama. |
| Frekuensi pembaruan | 1, 4, 16, dan 64 dtk setelah dimulai, lalu setiap 30 mnt | Seri penyelesaian geometris menyatu pada set kerja pasca-startup setiap daemon tanpa melakukan hardcoding penundaan pemanasan per perangkat, dan refresh status stabil selama 30 menit melacak pertumbuhan dan penyusutan set kerja secara bertahap selama masa pakai perangkat. |
Di pengontrol memori Linux cgroup v2
(mm/memcontrol.c:effective_protection), perlindungan memory.min efektif cgroup leaf dibatasi oleh memory.min yang dikonfigurasi pada cgroup induk
dan ancestor-nya. Menetapkan memory.min hanya pada direktori pid_<pid> leaf
sementara uid_<uid>/memory.min adalah 0 akan menghasilkan perlindungan efektif nol.
Sebaliknya, menetapkan memory.min tetap hanya di bagian atas
/sys/fs/cgroup/system akan mendistribusikan perlindungan yang tidak diklaim di semua UID
dan proses turunan secara proporsional (memory_recursiveprot), sehingga memungkinkan proses diagnostik
atau sekunder yang berbagi uid_1000 (android.uid.system) untuk menyedot
perlindungan dari surfaceflinger dan audioserver.
Untuk memberikan isolasi per daemon yang tepat, SystemMemoryBudgetManager menulis
perlindungan di ketiga tingkat hierarki cgroup v2 pada setiap refresh,
seperti yang ditunjukkan pada gambar 1:
- Node proses leaf (
pid_<pid>/memory.min): Ditetapkan ke batas bawah set kerja 90% (diskalakan) proses. - Node UID (
uid_<uid>/memory.min): Ditetapkan ke jumlah persis dari batas bawah leafpid_*yang dikelola, sehingga proses yang tidak dikelola yang berbagi UID tersebut (seperti daemonAID_SYSTEMatau paketsharedUserId="android.uid.system"lainnya) memilikimemory.min = 0dan tidak dapat mengklaim perlindungan. - Slice tingkat teratas (
/sys/fs/cgroup/system/memory.mindan/sys/fs/cgroup/apps/memory.min): Ditetapkan ke jumlah persis dariuid_*turunannya. Setiap nilaimemory.lowyang tidak berlaku pada node terkelola akan dihapus menjadi0, dan setiap direktoriuid_*yang dikelola pada pemuatan ulang sebelumnya (seperti peluncur Layar utama sebelumnya setelah pengguna beralih peluncur) akan direset ke0.
Gambar 1. Delegasi batas perlindungan tiga tingkat di seluruh slice cgroup.
Alasan memory.min digunakan, bukan memory.low pada kernel MGLRU
Di LRU Multi-Generasi (MGLRU, mesin klaim ulang halaman default di kernel Android
6.6 dan yang lebih baru), memory.low dan memory.min berperilaku berbeda di
mm/vmscan.c:shrink_one:
memory.low(penundaan sekali-proses): Cgroup yang penggunaannya di bawahmemory.lowdiputar ke ujung LRU memcg (MEMCG_LRU_TAIL) dan dilewati untuk satu proses klaim kembali. Pada tahap berikutnya di bawah tekanan memori yang berkelanjutan, kernel akan mengklaim kembali cgroup secara penuh dan mencatat peristiwaMEMCG_LOWke dalam log. Dalam uji stres perangkat fisik dengan pemboros memori anonim yang meningkat hingga 85% dari RAM fisik,memory.lowmemungkinkanSystemUIdi smartwatch menyusut dari ~45 MB menjadi ~5 hingga 10 MB danaudioserverdi perangkat foldable 16 GB turun dari 15 MB menjadi 2 MB dibandingkan dengan batas minimum ~14 MB.memory.min(batas perlindungan ketat): Cgroup yang penggunaannya di bawahmemory.minakan dilewati oleh klaim ulang global. Seperti yang ditunjukkan pada gambar 2, di bawah beban kerja tekanan RAM 85% yang sama,memory.minhanya melepaskan 10% tail paling dingin dari setiap daemon dan menahanSystemUI,surfaceflinger, danaudioserverpada batas bawah 90% tanpa refault anonim dan tanpa peningkatan penghentian proseslmkd.
memory.min memberikan pemesanan fisik yang ketat yang cocok dengan perlindungan
penyematan PinnerService mlock yang digantikannya, dengan keuntungan bahwa
LRU kernel (bukan daftar file statis) memilih kode hot, heap, dan
halaman grafis yang tetap berada di memori.
Gambar 2. Retensi set kerja daemon di bawah tekanan memori yang meningkat.
Booting pra-pemanasan dan reklamasi cache file yang tidak dipetakan setelah booting
Mengganti mlock permanen PinnerService dari
config_defaultPinnerServiceFiles memerlukan koordinasi dua perilaku
waktu booting:
- Pra-pemanasan booting latar belakang satu kali (
PinnerService): MelewatiPinnerServicemlocktanpa memanaskan cache halaman akan mengalihkan pembacaan diskSystemUIAPK, ODEX, dan VDEX sebesar ~95 MB ke jalur booting sinkron saatSystemUIdimulai (OnBootPhase_550), sehingga menambahkan 300 hingga 450 md ke penyelesaian booting. Memanggilmadvise(MADV_WILLNEED)tidak cukup karenaforce_page_cache_radi kernel menjepit satu panggilanMADV_WILLNEEDke satu jendela readahead (biasanya 128 KB hingga 2 MB). Sebagai gantinya, saatSystemMemoryBudgetManager.shouldSkipDefaultSystemPinningaktif,PinnerServicememetakan setiap file diconfig_defaultPinnerServiceFilespada thread latar belakang selamaonStart, mengisi file secara sinkron ke dalam cache halaman denganOs.mlock, dan segera memanggilOs.munlock,munmap, danclose. Hal ini mempertahankan waktu booting cepat sekaligus tidak meninggalkan byte yang terkunci secara permanen sehingga halaman cold startup dapat dihapus nanti. - Mengecualikan dan mengklaim kembali cache pemindaian paket booting
system_server: Selama booting,PackageManagerServicememindai APK yang diinstal, sehingga menyisakan 1,5 hingga 2,5 GB cache halaman file dingin yang tidak dipetakan yang dibebankan ke cgroupsystem_server. Jika disertakan dalam penghitunganmemory.mindarisystem_server, cache cold boot tersebut akan memenuhi batas RAM global 10% dan secara proporsional memperkecil skala batas perlindungansurfaceflinger,SystemUI, danaudioserver. Untuk mencegah kekurangan batas,SystemMemoryBudgetManagermembacamemory.statuntuksystem_server, menghitung cache file yang tidak dipetakan sebagaimax(0, file - shmem - file_mapped), dan mengurangi cache yang tidak dipetakan tersebut darimemory.currentsebelum menghitung batas bawah 90%, seperti yang ditunjukkan pada gambar 3. Selain itu, 10 detik setelahPHASE_BOOT_COMPLETED, pengelola melakukan penulisan satu kali<unmapped_file> swappiness=0ke nodememory.reclaimdarisystem_serverdi Linux 6.2 dan kernel yang lebih baru untuk secara proaktif mengeluarkan cache pemindaian paket dingin tanpa menukar heap anonim atau mengeluarkan DEX dan halaman kode yang dipetakan. Pada kernel lama (sepertiandroid14-6.1) yang menolakswappiness=0denganEINVAL, pengelola akan melewati penulisanmemory.reclaim, bukan kembali ke penulisan reklamasi yang tidak memenuhi syarat yang akan menukar heap anonim selama booting.
Gambar 3. Konvergensi batas perlindungan dan klaim ulang cache setelah booting.
Persyaratan kernel dan overlay konfigurasi perangkat
SystemMemoryBudgetManager mengandalkan mem_cgroup_calculate_protection di
kernel Linux untuk menyebarkan memory.min di seluruh cgroup bertingkat. Kernel umum Android android15-6.6 dan android16-6.12 menyertakan dukungan perlindungan bertingkat MGLRU lengkap secara langsung. Perangkat yang menjalankan android14-6.1 dengan MGLRU
yang diaktifkan memerlukan tiga backport upstream di mm/vmscan.c dan mm/memcontrol.c
sehingga slice perantara kosong dan cgroup UID menyebarkan perlindungan ke cgroup proses
leaf:
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 dapat menyesuaikan atau menonaktifkan SystemMemoryBudgetManager menggunakan overlay resource framework berikut:
config_systemMemoryBudgetLowKb(integer, KB):0(default) membatasi jumlah semua batas minimummemory.minsebesar 10% dari total RAM fisik. Nilai positif menetapkan batas eksplisit dalam KB, dan nilai negatif menonaktifkanSystemMemoryBudgetManagerdi perangkat (mempertahankan penyematanmlockstatisPinnerServicelama).config_systemMemoryBudgetHighKb(bilangan bulat, KB):0(default) membiarkan/sys/fs/cgroup/system/memory.highpadamax. Nilai positif menetapkan batas atas slicememory.high(harus lebih besar dari atau sama dengan batas bawah).config_systemMemoryBudgetAdditionalSystemProcesses(string-array): Mencantumkan nama proses daemon vendor atau sistem native tambahan yang sangat penting untuk latensi di/sys/fs/cgroup/system(dicocokkan dengan/proc/<pid>/commatau nama dasarargv[0]di/proc/<pid>/cmdlineuntuk UID sistem dan vendor di bagian10000) untuk dilindungi dengan batas minimummemory.min90% bersama enam daemon sistem default. Gunakan overlay ini daripada menetapkanmemory.mindiinit.rckarenaSystemMemoryBudgetManagermenghitung ulanguid_<uid>/memory.minsebagai jumlah proses leaf terkelola dan menghapus nodeuid_*yang tidak dikelola pada setiap refresh. Misalnya, perangkat XR dapat melindungi daemon HAL kamera dan pelacakan spasialnya dengan overlay berikut:<string-array translatable="false" name="config_systemMemoryBudgetAdditionalSystemProcesses"> <item>android.hardware.perceptionhost</item> <item>auracamerahal</item> </string-array>config_systemUi(string): Nama paket aplikasi SystemUI platform, diselesaikan denganMATCH_SYSTEM_ONLY.
Untuk memeriksa lantai SystemMemoryBudgetManager dan node cgroup yang aktif di
perangkat, jalankan:
# Inspect policy state, resolved PIDs, and applied floors in dumpsys meminfo 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
Mengikat aplikasi sistem persisten dan latar belakang dengan anggaran memori
Meskipun SystemMemoryBudgetManager melindungi daemon interaktif dari klaim ulang
menggunakan batas minimum memory.min, banyak aplikasi sistem dan layanan platform
dengan hak istimewa lainnya berjalan di latar belakang dalam waktu lama sebagai proses PERSISTENT, layanan latar depan terikat, atau penyedia konten yang sering dikueri.
Tanpa batas memori eksplisit, proses ini tidak dibatasi hingga
mencapai batas Pembatas Memori multi-gigabyte (seperti 4 GB
hingga 10 GB untuk aplikasi yang terlihat dan 2 GB hingga 5 GB untuk aplikasi
latar belakang) atau tekanan memori global memicu aktivitas kswapd dan low-memory
killer (lmkd) di seluruh sistem.
Jika tidak dibatasi, proses sistem latar belakang sering kali mengumpulkan sejumlah besar memori dingin yang bukan bagian dari set kerja aktifnya:
- Cache halaman file tak terbatas: Layanan yang mengindeks media, menelusuri database,
atau menyinkronkan tabel kalender dan penyedia (seperti
AppSearch,MediaProvider, danCalendarProvider) memetakan atau melakukan streaming melalui file besar di disk. Tanpa batasmemory.highcgroup, halaman bersih yang didukung file dari pembacaan satu kali akan tetap dibebankan ke cgroup proses tanpa batas waktu, sehingga menggunakan ratusan megabyte RAM fisik. - Retensi heap anonim pasca-burst: Layanan yang mengalami lonjakan aktivitas
sementara, seperti burst penemuan BLE dan audio
Bluetooth, validasi TLS captive-portalNetworkStack, atau helper UI yang bertransisi ke latar belakang, dapat mempertahankan halaman heap anonim dingin lama setelah burst selesai.
Menerapkan deklarasi <memory-budget> yang dikalibrasi (batas ringan memory.high,
biasanya 30 MB hingga 190 MB) ke aplikasi sistem memberikan dua manfaat
utama:
- Klaim ulang halaman yang proaktif dan dilokalkan: Saat proses sistem melampaui
anggaran
memory.highyang dikonfigurasi, kernel Linux mengarahkan klaim ulang halaman khusus ke cgroup tersebut, mengeluarkan halaman yang didukung file dingin terlebih dahulu dan mengompresi halaman anonim yang tidak aktif ke ZRAM tanpa menunggu tekanan memori perangkat global. - RAM yang lebih banyak tersedia untuk aplikasi latar depan dan kumpulan aplikasi yang di-cache: Membatasi cache file cold di seluruh layanan sistem yang selalu aktif akan mengklaim kembali puluhan hingga ratusan megabyte RAM fisik di seluruh perangkat, sehingga mengurangi jank UI, menurunkan tekanan peluncuran kamera, dan menjaga lebih banyak aplikasi pengguna tetap aktif dalam status di-cache.
Mengonfigurasi anggaran memori aplikasi sistem
Aplikasi sistem menggunakan sintaksis manifes <memory-budget>, cascading status
proses, penskalaan kepadatan
tampilan, dan aturan resolusi klausa pencocokan
terakhir yang sama dengan aplikasi umum. Untuk mengetahui daftar lengkap
atribut, lihat referensi atribut XML.
OEM dapat mendeklarasikan elemen <memory-budget> langsung di dalam AndroidManifest.xml aplikasi sistem atau menggabungkannya dari file XML terpisah menggunakan properti additional_manifests di Android.bp. Berdasarkan konvensi, AOSP menyimpan
anggaran aplikasi sistem referensi dalam file *-budget.xml mandiri (baik di
frameworks/base/core/memory_budgets/ untuk paket platform inti atau bersama
modul individual seperti packages/modules/NetworkStack/memory_budgets/,
packages/modules/AppSearch/apk/, dan packages/services/Telephony/) dan
melampirkannya dengan additional_manifests:
android_app {
name: "TeleService",
manifest: "AndroidManifest.xml",
additional_manifests: ["Telephony-budget.xml"],
// ...
}
Cakupan tingkat paket (UID) versus tingkat proses (PID)
Apakah Anda mendeklarasikan anggaran dasar pengukuran tingkat paket (<application>) atau anggaran multiproses (<processes><process>) menentukan apakah kernel menerapkan memory.high di tingkat cgroup UID (/sys/fs/cgroup/uid_<uid>/memory.high) atau di tingkat cgroup per PID (/sys/fs/cgroup/uid_<uid>/pid_<pid>/memory.high), seperti yang ditunjukkan pada gambar 4:
- Anggaran tingkat paket (
<application>): Gunakan saat APK menjalankan satu proses di bawah UID khususnya sendiri (misalnya,Bluetooth,Nfc,NetworkStack,CalendarProvider,Traceur, atauAppSearch). - Anggaran tingkat proses (
<processes><process>): Gunakan saat APK berbagiandroid:sharedUserId(sepertiandroid.uid.phonedengan UID1001atauandroid.uid.systemdengan UID1000) dengan paket sistem lain sehingga proses lain yang berbagi UID tersebut tidak dibatasi bersama, atau saat satu APK menjalankan beberapa proses dengan peran memori yang berbeda (misalnya, daemonMediaProviderlatar belakang dan subproses UI:PhotoPicker).
Gambar 4. Batas memori tingkat UID versus tingkat PID.
Contoh berikut menunjukkan MediaProvider-budget.xml, yang mencakup anggaran berjenjang RAM ke proses MediaProvider default (<process>) dan anggaran berskala tampilan ke proses UI :PhotoPicker. Setiap atribut android:maxDeviceRamMb cocok dengan perangkat yang total
RAM fisiknya (MemTotal) berada pada atau di bawah batas MB yang ditentukan (atau berlaku
untuk kapasitas RAM apa pun jika dihilangkan). Klausa diurutkan dari default yang tidak dibatasi hingga nilai minimum maxDeviceRamMb terkecil sehingga aturan resolusi klausa pencocokan terakhir memilih tingkat yang berlaku paling ketat:
<?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>
Cara anggaran referensi AOSP dikalibrasi di perangkat Google Pixel
Anggaran memori aplikasi sistem referensi di AOSP dikalibrasi di seluruh perangkat Google Pixel yang mencakup RAM fisik 6 GB hingga 16 GB (termasuk ponsel, perangkat foldable, dan tablet 6 GB, 8 GB, 12 GB, dan 16 GB) serta resolusi layar mulai dari ~1,2 MP (720×1600) hingga ~4,5 MP (2076×2152).
Kalibrasi menggabungkan dua sumber data yang saling melengkapi: telemetri lapangan cgroup v2 di seluruh perangkat dan pemindaian memory.high perangkat fisik yang terkontrol di seluruh perjalanan penting pengguna (CUJ).
Analisis telemetri cgroup v2 tingkat fleet
Snapshot cgroup v2 berkala dikumpulkan di seluruh rangkaian perangkat dan dibagi
berdasarkan tingkat RAM fisik (≤8 GB, 12 GB, dan ≥16 GB) serta bucket status
proses (foreground, perceptible, background, dan cached). Enam
prinsip memandu analisis statistik:
- Menguraikan
memory.currentmenjadi set kerja versus cache file yang dapat diklaim kembali: Karenamemory.highmengatur biaya cgroup residen (memory.current), setiap snapshot diuraikan menggunakanmemory.statmenjadi heap anonim (anon), halaman anonim yang ditukar (swap), dan cache halaman yang didukung file (file), seperti yang ditunjukkan pada gambar 5. Total permintaan anonim yang tidak dapat dikompresi (anon + swapdi P99) menetapkan batas minimum set kerja untuk anggaran sehingga proses tidak berisiko kehabisan ZRAM, sementara kesenjangan yang besar antaramemory.currentP99 dananon + swapP99 menunjukkan cache halaman file yang dapat diklaim kembali olehmemory.high, asalkan cache tersebut tidak dipetakan dan dingin. - Memperhitungkan memori yang tidak dapat diklaim kembali oleh
memory.high: Tidak semua file dan memori bersama adalah cold cache. Halaman yang dikunci (unevictabledimemory.stat, seperti memori bersama yang dikunci denganmlockatau RAM tamu yang dikunci dari virtual machine yang proses host-nya ditagih ke cgroup aplikasi) menetapkan batas minimum di bawah anggaran, dan halaman yang dipetakan (file_mapped) sering kali merupakan bagian dari set kerja aktif. Periksaunevictable,shmem, danfile_mappedsebelum memperlakukan memori file sebagai dapat diklaim kembali. Misalnya, sekitar 100 MB memoriAppSearchdikunci dan tidak dapat dikeluarkan, sehingga anggarannya mencakup batas minimum tersebut ditambah set kerja host panasnya, dengan ruang untuk pertumbuhan region yang dikunci. - Memfilter dilusi status tidak ada aktivitas: Penyedia konten (
CalendarProvider) dan alat developer on demand (Traceur) menghabiskan 70% hingga 99,9% snapshot lapangan tidak ada aktivitas pada ~1 MB hingga 3 MB. Menghitung persentil mentah di semua snapshot akan sangat mengurangi estimasi P95 dan P99. Sebagai gantinya, persentil dan interval kepercayaan dihitung berdasarkan snapshot aktif yang tidak diencerkan (memfilter snapshotCACHEDdan snapshot dasar pengukuran tidak ada aktivitas). - Gunakan interval keyakinan yang dikelompokkan berdasarkan perangkat: Karena satu perangkat
memberikan banyak snapshot berkala dari waktu ke waktu, memperlakukan snapshot sebagai
sampel independen akan meremehkan ketidakpastian tail. Semua estimasi set kerja P95 dan P99 dievaluasi menggunakan interval keyakinan 95% yang dikelompokkan menurut perangkat secara konservatif (menggunakan jumlah perangkat yang berbeda
N_devsebagai ukuran sampel efektif). - Memperhitungkan lonjakan sementara dengan
memory.peak: Pengambilan sampel berkala dapat melewatkan lonjakan alokasi tinggi yang berumur pendek (seperti validasi TLS captive-portalNetworkStackdan pemeriksaan DNS serentak, atau inisialisasi A2DP dan BLEBluetooth). Untuk layanan bursty, anggaran diukur untuk mencakup persentil ke-90 hingga ke-95 dari batas maksimummemory.peakkernel seumur hidup di seluruh tingkat RAM. - Pastikan tingkat RAM mencerminkan RAM, bukan generasi perangkat: Perangkat
yang lebih baru cenderung memiliki lebih banyak RAM dan lebih banyak fitur, sehingga set kerja yang
berkembang seiring tingkat RAM mungkin sebenarnya berkembang seiring fitur. Sebelum menambahkan
tingkat
maxDeviceRamMb, bagi data berdasarkan model perangkat. Misalnya,com.android.phonemencapaianon + swapP99 yang sama (~85 hingga 90 MB) pada ponsel 12 GB dan 16 GB dari generasi yang sama, sedangkan perangkat foldable 12 GB yang lebih lama menggunakan 40 MB. Oleh karena itu, anggarannya menggunakan satu nilai tanpa tingkat RAM, sehingga perangkat RAM yang lebih rendah yang mengirimkan fitur telepon yang lebih baru tidak kekurangan anggaran.
Gambar 5. Set kerja versus cache file yang dapat diklaim kembali.
CUJ perangkat fisik dan pemindaian penskalaan layar
Untuk memvalidasi anggaran yang diperoleh dari telemetri dan mengkalibrasi anggaran
proporsional tampilan (seperti :PhotoPicker) dan anggaran latar belakang khusus status (seperti
Traceur), pemindaian memory.high langsung dijalankan di perangkat fisik yang mencakup
RAM 6 GB hingga 16 GB:
- Menemukan titik lutut kesalahan ulang nol: Saat mendorong CUJ menyeluruh (seperti pengguliran cepat petak foto, penjelajahan album, geser pratinjau foto dan video resolusi tinggi layar penuh, serta rekaman pelacakan dan penyimpanan),
memory.highditurunkan saat mengukur penghitungmemory.statcgroup (workingset_refault_anon,workingset_refault_file,pgscan, danpgsteal) danmemory.events(high). Seperti yang diilustrasikan dalam gambar 6, anggaran optimal berada tepat di atas titik lutut kesalahan ulang nol. Zero-refault knee adalah nilai minimum saat kernel mengklaim kembali cache file satu kali yang dingin (pgsteal > 0) tanpa memicu thrashing set kerja aktif (workingset_refault == 0). - Memvalidasi penskalaan piksel tampilan di berbagai resolusi: Pengujian
:PhotoPickerdi empat resolusi tampilan fisik dan emulasi dari ~1,2 MP (720×1600) hingga ~4,5 MP (layar dalam yang dibentangkan 2076×2152) mengonfirmasi bahwa set kerja bitmap Glide dan ViewPager2 yang aktif diskalakan secara linear dengan jumlah piksel tampilan. Baseline non-tampilan juga bervariasi menurut perangkat: pada jumlah piksel yang hampir sama, titik belok tanpa kesalahan adalah sekitar 140 MB pada layar luar perangkat foldable 16 GB versus 110 hingga 125 MB pada ponsel 6 GB. Dasar pengukuran 85 MB ditambah 25 byte per piksel tampilan (android:maxMb="85"danandroid:additionalBytesPerDisplayPixel="25") tetap berada di atas batas yang diukur pada setiap layar yang diuji (~110 MB pada HD+, ~145 MB pada FHD+, dan ~190 MB pada layar yang dibentangkan). - Memverifikasi pembersihan sampah memori ART dalam status latar belakang: Di cgroup v2,
halaman image framework dan
boot.artyang dibagikan Zygote tetap dibebankan ke cgroup Zygote dan diperlakukan sebagai ruang kebal selama pembersihan sampah memori mark-compact (CMC) serentak ART. Pengujian stres mengonfirmasi bahwa saat aplikasi UI sistem bertransisi kebackground, pengetatanmemory.high(misalnya, menjadi 30 MB diTraceur) akan membatasi heap pribadi dan cache halaman dengan rapi tanpa menyebabkan thrashing GC atau aktivitas pertukaran.
Gambar 6. Menemukan titik belok zero-refault selama CUJ.
Ringkasan anggaran aplikasi sistem referensi AOSP
Tabel berikut merangkum anggaran referensi yang dikalibrasi di AOSP di seluruh tingkat RAM dan status proses:
| Paket atau proses sistem | Cakupan | RAM ≤8 GB | RAM 12 GB | RAM ≥16 GB | Faktor pendorong kalibrasi utama |
|---|---|---|---|---|---|
com.android.bluetooth |
UID (<application>) |
80 MB | 95 MB | 110 MB | Mencakup burst memory.peak masa aktif P90 (~75 hingga 110 MB) dan memory.current aktif >2x P99. |
com.android.nfc |
UID (<application>) |
50 MB | 60 MB | 60 MB | Mencakup Host Card Emulation P99 aktif (hingga ~50 MB) dan P90 hingga P95 memory.peak sambil memangkas cache file dingin. |
com.android.providers.calendar |
UID (<application>) |
70 MB default (latar depan) 50 MB perceptible & background |
Set kerja aktif tidak bervariasi di seluruh tingkat RAM. Anggaran latar belakang mempertahankan headroom anonim untuk alarm pengingat sekaligus memangkas cache halaman SQLite selama sinkronisasi. | ||
com.android.traceur |
UID (<application>) |
85 MB default (latar depan & terlihat) 30 MB background |
Mempertahankan headroom penuh sebesar 85 MB selama perekaman dan ekspor rekaman aktivitas aktif (TraceService), sekaligus membatasi status tidak ada aktivitas dan siaran pada 30 MB. |
||
com.android.providers.media.module (utama) |
PID (<process>) |
60 MB | 75 MB | 85 MB | Menyediakan ruang tambahan sekitar 10 hingga 30 MB di atas P99 anon + swap sekaligus mengklaim kembali cache file thumbnail dan SQLite yang tidak aktif. |
com.android.providers.media.module:PhotoPicker |
PID (<process>) |
85 MB + 25 byte per piksel (~110 MB di HD+, ~145 MB di FHD+, ~190 MB di layar lipat ~4,5 MP) |
Menskalakan secara proporsional dengan jumlah piksel tampilan (additionalBytesPerDisplayPixel="25") agar sesuai dengan knee set kerja bitmap Glide. |
||
com.android.networkstack |
UID (<application>) |
65 MB | 70 MB | 85 MB | Sebagian besar memori anonim, berukuran masa aktif P95 memory.peak untuk mencakup burst DHCP, DNS, dan TLS captive portal. |
com.android.appsearch.apk |
UID (<application>) |
130 MB | Mencakup ~100 MB memori terkunci yang tidak dapat dikeluarkan ditambah set kerja host panas ~5 MB, dengan ruang untuk region terkunci untuk berkembang. Nol kesalahan referensi yang diukur pada ≥125 MB saat cold page cache (hingga ~330 MB di P99) diklaim kembali. | ||
com.android.phone (TeleService) |
PID (<process>) |
120 MB | Dicakup per PID pada UID bersama 1001. Set kerja melacak generasi perangkat, bukan RAM, sehingga satu anggaran berada ~30 MB di atas anon + swap P99 tertinggi per model. |
||
Cara OEM dapat mengkalibrasi ulang anggaran aplikasi sistem untuk perangkat mereka sendiri
OEM yang menyesuaikan aplikasi sistem (misalnya, menambahkan profil Bluetooth vendor,
ekstensi telepon kustom, atau pengindeks media OEM) atau mengirimkan layanan sistem
tambahan yang telah diinstal sebelumnya dapat mengalokasikan ulang anggaran yang ada atau membuat file
*-budget.xml baru untuk portofolio hardware mereka.
Mengumpulkan profil memori cgroup v2 aktif
Untuk setiap proses sistem target, baca node memori cgroup v2-nya di bagian
/sys/fs/cgroup/uid_<uid>/pid_<pid>/ di seluruh workload dan tingkat RAM
yang representatif:
memory.current: Memori residen saat ini yang dibebankan ke cgroup (tidak termasuk halaman yang dibagikan Zygote)memory.peak: Batas maksimum puncakmemory.currentsepanjang waktu sejak proses dimulaimemory.swap.current: Penggunaan swap terkompresi saat ini di ZRAMmemory.stat: Pengelompokananon,file,pgscan,pgsteal,workingset_refault_anon, danworkingset_refault_filememory.events: Jumlah kumulatif pelanggaranhigh(peristiwa throttling dan klaim kembalimemory.high)
Saat menggabungkan telemetri dari perangkat dogfood atau lapangan, pisahkan status proses aktif (TOP, FOREGROUND_SERVICE, binding aktif, dan sinkronisasi aktif) dari status CACHED nonaktif atau PERSISTENT nonaktif sehingga snapshot nonaktif tidak memiringkan penghitungan set kerja P95 dan P99 Anda ke bawah.
Memisahkan heap yang tidak dapat dikompresi dari cache file yang dapat diklaim kembali
Bandingkan persentil ke-99 dari anon + swap dengan persentil ke-99 dari
memory.current:
- Layanan yang didominasi cache file (
file≫anon, seperti penyedia database, pengindeks penelusuran, dan daemon log): Tetapkanandroid:maxMbuntuk memberikan ruang yang nyaman (biasanya 1,5x hingga 4x) di atas P99anon + swapditambah jendela kerja untuk halaman file panas. Konfigurasi ini memungkinkan kernel terus mengeluarkan halaman file dingin yang tidak dipetakan tanpa menyentuh heap anonim. Jikaunevictableataufile_mappedberukuran besar (seperti dengan memori terkunci atau database yang dipetakan memori), hitung jejak tersebut sebagai set kerja juga. - Layanan yang didominasi heap anonim atau bursty (
anonmerupakan sebagian besarmemory.current, seperti stack jaringan atau konektivitas): Ukuranandroid:maxMbuntuk mencakup P90 hingga P95 darimemory.peaksehingga burst sementara tidak memicu swap-out ZRAM sinkron pada thread yang sensitif terhadap latensi. - Proses UI yang intensif tampilan (seperti pemilih, galeri, atau helper UI sistem): Ukur jejak non-UI dasar pengukuran dan jejak bitmap inkremental per megapiksel di seluruh tampilan resolusi terendah dan tertinggi, dan nyatakan anggaran menggunakan
android:maxMbplusandroid:additionalBytesPerDisplayPixel.
Menyapu memory.high di perangkat fisik
Sebelum mengalokasikan anggaran baru ke build, gunakan am memory-limiter manual (atau
tulis langsung ke node cgroup memory.high proses pada build userdebug)
untuk menguji batas kandidat saat menjalankan pengujian CUJ otomatis:
# Override memory.high for a specific PID to 60 MB during a CUJ test
adb shell am memory-limiter manual <PID> 60MBPantau memory.stat dan memory.events sebelum dan setelah CUJ:
- Anggaran terlalu rendah:
workingset_refault_anonatauworkingset_refault_filemelonjak tajam selama CUJ,memory.swap.currentterus bertambah selama pekerjaan latar depan aktif, atau frame CUJ atau latensi Binder mengalami regresi. Tingkatkan anggaran melebihi titik belok default. - Anggaran terlalu tinggi:
memory.events:hightetap0bahkan setelah workload streaming file atau pengindeksan yang berat, danfiledimemory.statbertambah tanpa batas dengan halaman cold. Perketat anggaran untuk set kerja yang aktif. - Anggaran dikalibrasi dengan baik:
memory.currentstatus stabil tetap berada di bawahmemory.highselama operasi normal. Selama burst file atau cache yang berat,pgstealmengklaim kembali halaman file cold, sementaraworkingset_refault_anontetap mendekati nol dan latensi CUJ tidak berubah.