Android 17 dan yang lebih tinggi menyertakan Pembatas Memori, yaitu layanan sistem yang memantau dan membatasi penggunaan memori proses aplikasi menggunakan cgroup v2 Linux. Pembatas Memori mencegah aplikasi individual mengonsumsi memori sistem secara tidak proporsional, yang mengurangi tekanan memori secara keseluruhan dan mencegah penghentian agresif proses penting di latar depan dan dalam cache karena memori rendah.
Mekanisme
Pembatas Memori terintegrasi dengan Layanan Pengelola Aktivitas (AMS) untuk melacak peristiwa siklus proses dan perubahan status proses. Pembatas Memori menerapkan batas memori menggunakan hierarki cgroup v2 kernel Linux.
Untuk mendukung Pembatas Memori, kernel perangkat harus mengaktifkan cgroup v2 dan pengontrol memory. Layanan ini secara khusus mengandalkan atribut berikut:
memory.high- Batas yang dapat dilewati. Jika terlampaui, proses akan dibatasi dan kernel akan mencoba merebut kembali halaman secara proaktif dari proses tersebut.
memory.swap.max- Membatasi jumlah maksimum ruang swap (seperti ZRAM) yang dapat digunakan proses.
Dampak pada aplikasi
Aplikasi yang beroperasi dalam batas memorinya tidak terpengaruh oleh Pembatas Memori.
Saat aplikasi melampaui batas memory.high, kernel akan mengeluarkan memori yang didukung file bersih aplikasi dan menukar memori anonim yang tidak aktif untuk menjaga aplikasi tetap dalam batas. Sebagai akibat dari aktivitas penggantian dan penghapusan halaman ini, aplikasi mungkin mengalami pembatasan eksekusi sementara, tetapi aplikasi akan terus berjalan.
Dalam situasi ekstrem—seperti kebocoran memori yang tidak terkontrol saat aplikasi terus mengalokasikan memori anonim setelah ruang swap habis—aplikasi gagal mengalokasikan memori dan dihentikan.
Pemantauan proses
Pembatas Memori memantau proses aplikasi (UID >= 10000) secara default. Proses sistem inti dikecualikan untuk menjaga stabilitas sistem penting.
Pembatas Memori menetapkan batas memori berdasarkan status visibilitas proses:
Proses yang terlihat: Proses yang menghosting UI yang terlihat oleh pengguna (seperti aktivitas yang saat ini difokuskan atau interaksi aktif). Karena menampilkan UI memerlukan set kerja yang lebih besar untuk pipeline rendering dan grafis, proses yang terlihat menerima batas memori yang lebih besar.
Proses yang tidak terlihat: Proses yang melakukan pekerjaan di latar belakang tanpa menampilkan UI (seperti layanan latar belakang atau penerima siaran). Karena tidak merender komponen UI, fungsi ini beroperasi di bawah batas yang lebih ketat.
Tabel berikut memetakan status proses tertentu ke klasifikasi batas memori:
| Status proses | Batas memori |
|---|---|
PERSISTENT | Tidak dibatasi |
PERSISTENT_UI | Tidak dibatasi |
TOP | Terlihat |
BOUND_TOP | Terlihat |
FOREGROUND_SERVICE | Tidak terlihat |
BOUND_FOREGROUND_SERVICE | Tidak terlihat |
IMPORTANT_FOREGROUND | Terlihat |
IMPORTANT_BACKGROUND | Tidak terlihat |
TRANSIENT_BACKGROUND | Tidak terlihat |
BACKUP | Tidak terlihat |
SERVICE | Tidak terlihat |
RECEIVER | Tidak terlihat |
TOP_SLEEPING | Terlihat |
HEAVY_WEIGHT | Tidak terlihat |
HOME | Tidak terlihat |
LAST_ACTIVITY | Tidak terlihat |
CACHED_ACTIVITY | Di-cache |
CACHED_ACTIVITY_CLIENT | Di-cache |
CACHED_RECENT | Di-cache |
CACHED_EMPTY | Di-cache |
Dalam status di-cache, proses dibekukan, lalu diklaim kembali secara maksimal.
Jika proses melampaui batas memory.high yang ditetapkan, Pembatas Memori akan mendeteksi peristiwa tersebut dan dapat memicu tindakan diagnostik, seperti merekam profil memori atau mencatat anomali ke statsd.
Konfigurasi
Di Android 17 dan yang lebih tinggi, Pembatas Memori menyediakan file konfigurasi default platform standar di partisi sistem, sekaligus mendukung penggantian khusus perangkat opsional di partisi vendor:
- Konfigurasi default sistem:
/system/etc/memory-limiter-config.xml - Penggantian vendor (opsional):
/vendor/etc/memory-limiter-config.xml
Pembatas Memori memeriksa /vendor/etc/memory-limiter-config.xml terlebih dahulu.
Jika ada, konfigurasi vendor akan digunakan; jika tidak, konfigurasi akan melakukan fallback ke
konfigurasi sistem default di /system/etc/memory-limiter-config.xml.
Format XML
File konfigurasi mengikuti skema yang ditentukan dalam
memory-limiter-config.xsd. File menentukan beberapa set batas yang diurutkan berdasarkan
memori yang tersedia; layanan memilih set batas yang paling cocok berdasarkan
RAM yang tersedia di perangkat. Semua nilai memori ditentukan dalam mebibyte (MiB).
<MemoryLimiterConfig>
<version>1</version>
<configList>
<!-- RAM minimums account for MemTotal excluding carve-outs. -->
<limitSet>
<!-- Limits for 16GB RAM device (MemTotal >= 13GiB): 10G/5G/5G/5G -->
<minimumRequiredMemTotal>13312</minimumRequiredMemTotal>
<memVisible>10240</memVisible>
<memNotVisible>5120</memNotVisible>
<swapVisible>5120</swapVisible>
<swapNotVisible>5120</swapNotVisible>
</limitSet>
<limitSet>
<!-- Limits for 12GB RAM device (MemTotal >= 10GiB): 8G/4G/4G/4G -->
<minimumRequiredMemTotal>10240</minimumRequiredMemTotal>
<memVisible>8192</memVisible>
<memNotVisible>4096</memNotVisible>
<swapVisible>4096</swapVisible>
<swapNotVisible>4096</swapNotVisible>
</limitSet>
<limitSet>
<!-- Limits for 8GB RAM device (MemTotal >= 6.5GiB): 5G/3G/3G/3G -->
<minimumRequiredMemTotal>6656</minimumRequiredMemTotal>
<memVisible>5120</memVisible>
<memNotVisible>3072</memNotVisible>
<swapVisible>3072</swapVisible>
<swapNotVisible>3072</swapNotVisible>
</limitSet>
<limitSet>
<!-- Limits for 6GB RAM device (MemTotal >= 4.5GiB): 4G/2G/2G/2G -->
<minimumRequiredMemTotal>4608</minimumRequiredMemTotal>
<memVisible>4096</memVisible>
<memNotVisible>2048</memNotVisible>
<swapVisible>2048</swapVisible>
<swapNotVisible>2048</swapNotVisible>
</limitSet>
<limitSet>
<!-- Limits for 4GB RAM device (MemTotal >= 3GiB): 2G/1G/1G/1G -->
<minimumRequiredMemTotal>3072</minimumRequiredMemTotal>
<memVisible>2048</memVisible>
<memNotVisible>1024</memNotVisible>
<swapVisible>1024</swapVisible>
<swapNotVisible>1024</swapNotVisible>
</limitSet>
</configList>
</MemoryLimiterConfig>
version- Bilangan bulat positif yang mengidentifikasi versi konfigurasi. Nilai ini harus berupa
1. minimumRequiredMemTotalSistem minimum
MemTotal(dalam MiB) yang diperlukan agar set batas ini dapat diterapkan. Layanan mengevaluasi hal ini terhadap total memori yang tersedia yang dilaporkan oleh kernel di/proc/meminfo.Memahami alokasi memori: Nilai
MemTotalkernel mencerminkan DRAM fisik yang dapat diakses oleh sistem operasi setelah alokasi memori hardware dan firmware dikurangi. Penyisihan RAM untuk komponen hardware khusus seperti GPU, modem baseband, ISP kamera, lingkungan eksekusi yang aman, dan hypervisor, biasanya menggunakan antara 500 MiB dan lebih dari 1 GiB memori fisik.Karena
MemTotallebih rendah daripada DRAM fisik yang diiklankan perangkat, nilai minimumminimumRequiredMemTotalmencakup margin untuk alokasi ini. Misalnya, konfigurasi yang menargetkan perangkat 16 GB menentukanminimumRequiredMemTotalsebesar13312(13 GiB), bukan16384(16 GiB), dan tingkat untuk perangkat 12 GB menentukan10240(10 GiB). Hal ini memastikan bahwa setiap perangkat sesuai dengan tingkat yang dimaksudkan, terlepas dari variasi alokasi tingkat board.memVisibleBatas memori ringan (
memory.high) dalam MiB yang diterapkan pada proses yang terlihat.memNotVisibleBatas memori ringan (
memory.high) dalam MiB yang diterapkan pada proses yang tidak terlihat.swapVisibleBatas ruang swap (
memory.swap.max) dalam MiB yang diterapkan pada proses yang terlihat.swapNotVisibleBatas ruang swap (
memory.swap.max) dalam MiB yang diterapkan pada proses yang tidak terlihat.
Batas platform standar
Di Android 17 dan yang lebih baru, platform menentukan batas memori dan swap standar di /system/etc/memory-limiter-config.xml di seluruh tingkat RAM fisik umum:
| Menargetkan RAM fisik |
Minimum yang diperlukan MemTotal (minimumRequiredMemTotal) |
Batas memori yang terlihat (memVisible) |
Batas memori tidak terlihat (memNotVisible) |
Batas penukaran yang terlihat (swapVisible) |
Batas penukaran yang tidak terlihat (swapNotVisible) |
|---|---|---|---|---|---|
| 16 GB | 13.312 MiB (13 GiB) | 10.240 MiB (10 GiB) | 5.120 MiB (5 GiB) | 5.120 MiB (5 GiB) | 5.120 MiB (5 GiB) |
| 12 GB | 10.240 MiB (10 GiB) | 8.192 MiB (8 GiB) | 4.096 MiB (4 GiB) | 4.096 MiB (4 GiB) | 4.096 MiB (4 GiB) |
| 8 GB | 6.656 MiB (6,5 GiB) | 5.120 MiB (5 GiB) | 3.072 MiB (3 GiB) | 3.072 MiB (3 GiB) | 3.072 MiB (3 GiB) |
| 6 GB | 4.608 MiB (4,5 GiB) | 4.096 MiB (4 GiB) | 2.048 MiB (2 GiB) | 2.048 MiB (2 GiB) | 2.048 MiB (2 GiB) |
| 4 GB | 3.072 MiB (3 GiB) | 2.048 MiB (2 GiB) | 1.024 MiB (1 GiB) | 1.024 MiB (1 GiB) | 1.024 MiB (1 GiB) |
Prinsip batas memori
Konfigurasi Pembatas Memori dirancang berdasarkan prinsip platform berikut:
Konsistensi ekosistem dan kompatibilitas aplikasi: Batas memori yang konsisten di seluruh perangkat memastikan performa aplikasi yang dapat diprediksi di seluruh ekosistem Android. Aplikasi dikembangkan dan diuji berdasarkan ekspektasi memori standar; mempertahankan batas platform yang seragam akan menghindari throttling yang tidak terduga atau penghentian prematur.
Alokasi resource proporsional: Batas platform dikalibrasi sesuai dengan kapasitas RAM fisik:
- Proses yang terlihat: Mengalokasikan sekitar 1/2 hingga 2/3 dari total RAM fisik untuk mendukung workload UI, komposisi, dan rendering yang aktif.
- Proses yang tidak terlihat: Dialokasikan sekitar 1/4 hingga 1/3 dari total RAM fisik untuk tugas latar belakang.
Penerapan universal: Batas berlaku secara seragam untuk semua proses aplikasi di perangkat (UID >= 10000), termasuk aplikasi sistem dan OEM yang telah diinstal sebelumnya. Pembatas Memori tidak mendukung daftar yang diizinkan untuk mengecualikan aplikasi tertentu, sehingga memastikan tata kelola memori yang adil di semua aplikasi.
Tidak adanya API kueri runtime: Di Android 17 dan yang lebih tinggi, aplikasi tidak dapat mengkueri batas memori yang ditetapkan secara terprogram saat runtime. Batas platform standar ditentukan dengan margin yang besar sehingga aplikasi yang berperilaku baik dapat beroperasi tanpa batasan selama penggunaan normal.
Dinamika swap dan pelepasan kernel: Saat proses aplikasi mendekati batas
memory.high, kernel Linux mengarahkan pelepasan memori secara khusus ke cgroup proses tersebut. Hal ini mencakup penghapusan halaman yang didukung file yang tidak aktif dan menukar halaman anonim dingin ke ZRAM, sehingga menjaga kelancaran sistem tanpa memaksakan tekanan memori global.
Perintah shell
Perintah am memory-limiter memungkinkan developer dan integrator sistem berinteraksi dengan layanan saat runtime untuk pengembangan, pengujian, dan proses debug:
am memory-limiter <SUB-COMMAND>status
Sub-perintah status melaporkan status operasional dan metrik aktif
Pembatas Memori:
adb shell am memory-limiter statusContoh output:
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
Kolom utama dalam output mencakup:
monitoring- Menunjukkan apakah Pembatas Memori sedang aktif memantau proses.
visibleMemdannotVisibleMem- Batas memori absolut yang dihitung (
memory.high) saat ini diterapkan untuk setiap status visibilitas. visibleSwapdannotVisibleSwap- Batas penukaran absolut yang dihitung (
memory.swap.max) yang saat ini diterapkan untuk setiap status visibilitas. events- Jumlah proses yang telah melampaui batas yang ditetapkan.
processes- Jumlah proses yang dipantau saat ini.
abaikan
Sub-perintah ignore mengecualikan UID tertentu atau semua proses
dari pembatasan memori untuk sementara. Hal ini berguna untuk tolok ukur performa, pengujian
tekanan, atau mendiagnosis perilaku memori:
# Ignore a specific UID adb shell am memory-limiter ignore 10087# Ignore all processes (temporarily disables limiting) adb shell am memory-limiter ignore all# Resume normal limiting operation adb shell am memory-limiter ignore none
manual
Sub-perintah manual menggantikan batas yang dihitung untuk proses tertentu
berdasarkan ID proses (PID) dengan nilai absolut kustom dalam byte. Nilai harus berupa
bilangan bulat, tetapi dapat menyertakan akhiran MB untuk menunjukkan MiB atau akhiran GB untuk
menunjukkan GiB:
# Set a 1GiB limit for PID 1234 adb shell am memory-limiter manual 1234 1073741824# Set a 1GiB limit for PID 1234 adb shell am memory-limiter manual 1234 1024MB# Set a 1GiB limit for PID 1234 adb shell am memory-limiter manual 1234 1GB# Remove the manual override for PID 1234 adb shell am memory-limiter manual 1234 none
Penggantian manual hanya berlaku selama masa aktif instance proses tertentu tersebut. Jika proses dimulai ulang, proses akan kembali ke batas standar berdasarkan statusnya.
Penggantian manual tidak dapat melampaui batas sistem fisik.