Android 17 dan yang lebih tinggi mendukung Pembatas Memori, yang merupakan layanan sistem yang memantau dan membatasi penggunaan memori proses aplikasi menggunakan cgroup v2 Linux. Pembatas Memori mencegah aplikasi individual mengonsumsi memori sistem secara berlebihan, yang mengurangi tekanan memori di seluruh sistem dan mencegah penghentian paksa (killing) proses penting yang agresif karena kehabisan memori (OOM).
Mekanisme
Pembatas Memori terintegrasi dengan Layanan Pengelola Aktivitas (AMS) untuk melacak peristiwa siklus proses dan perubahan status proses. Pembatas Memori menerapkan batas memori menggunakan sistem file cgroup v2 kernel Linux.
Untuk menggunakan Pembatas Memori, kernel perangkat harus mendukung pengontrol cgroup v2 dan memory. Layanan ini secara khusus mengandalkan atribut berikut:
memory.high- Batas yang dapat dilewati. Jika terlampaui, proses akan di-throttle dan kernel akan mencoba merebut kembali memori darinya.
memory.swap.max- Membatasi jumlah ruang swap yang dapat digunakan proses.
Dampak pada aplikasi
Aplikasi yang tidak melebihi batas memorinya tidak terpengaruh oleh Pembatas Memori.
Saat aplikasi melampaui batas memory.high, kernel akan mengeluarkan memori yang didukung file aplikasi dan menukar memori anonimnya agar aplikasi tetap berada dalam batas. Akibat pengusiran dan pertukaran, aplikasi mungkin berjalan lebih lambat.
Pada kasus ekstrem, jika aplikasi terus mengalokasikan memori anonim dan perangkat kehabisan ruang swap, aplikasi mungkin gagal mengalokasikan memori, dan akibatnya cenderung error.
Pemantauan proses
Pembatas Memori memantau proses aplikasi (UID >= 10000) secara default. Proses sistem umumnya dikecualikan untuk membantu memverifikasi stabilitas sistem inti.
Pembatas Memori menetapkan batas memori berdasarkan status proses:
Proses yang terlihat dapat dirasakan oleh pengguna, seperti aktivitas latar depan, layanan latar depan, atau status lain yang dapat dirasakan jank-nya.
Proses yang tidak terlihat adalah proses latar belakang yang tidak berinteraksi dengan atau terlihat oleh pengguna.
Tabel berikut memetakan status proses tertentu ke 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.
Saat proses melampaui batas memory.high yang ditetapkan, Pembatas Memori
mendeteksi peristiwa tersebut dan dapat memicu tindakan pen-debug-an, seperti merekam profil
memori atau mencatat anomali ke statsd.
Konfigurasi
Konfigurasi Pembatas Memori menggunakan file XML yang berada di partisi vendor. Konfigurasi memungkinkan Anda menyesuaikan batas memori absolut berdasarkan batasan memori spesifik perangkat.
Jalur file:
/vendor/etc/memory-limiter-config.xmlKonfigurasi default: Jika file konfigurasi tidak ditemukan, atau jika file tersebut tidak dapat dibaca atau tidak valid, Pembatas Memori akan dinonaktifkan.
Format XML
File konfigurasi mengikuti skema yang ditentukan dalam
memory-limiter-config.xsd. File ini memungkinkan Anda menentukan beberapa set batas; layanan memilih kecocokan terbaik berdasarkan RAM yang tersedia di perangkat. Semua nilai memori ditentukan dalam satuan mebibyte (MiB).
<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- Bilangan bulat positif yang mengidentifikasi versi konfigurasi. Nilai ini harus 1.
minimumRequiredMemTotal- Memori sistem yang tersedia minimum yang diperlukan agar batas ini ditetapkan sebagai valid.
memVisible- Batas memori (
memory.high) yang diizinkan untuk proses yang terlihat. memNotVisible- Batas memori (
memory.high) yang diizinkan untuk proses yang tidak terlihat. swapVisible- Batas penggantian (
memory.swap.max) yang diizinkan untuk proses yang terlihat. swapNotVisible- Batas penggantian (
memory.swap.max) yang diizinkan untuk proses yang tidak terlihat.
Panduan batas memori perangkat
Saat mengonfigurasi batas memori untuk perangkat, pertimbangkan panduan berikut:
Menyesuaikan batas dengan kemampuan hardware: OEM perangkat dapat menetapkan batas yang disesuaikan dengan kemampuan hardware perangkat mereka. Android merekomendasikan rentang berikut:
- Proses yang terlihat: Setidaknya 1/2 dan paling banyak 2/3 dari total RAM fisik.
- Proses yang tidak terlihat: 1/4 hingga 1/3 dari total RAM fisik. OEM dapat membuat penentuan yang berbeda berdasarkan kemampuan perangkat dan kasus penggunaan.
Tidak ada API runtime untuk aplikasi: Mulai Android 17 (SDK 37), aplikasi tidak memiliki API untuk mengkueri batas memori saat runtime. OEM harus mempertimbangkan hal ini dan menghindari penetapan batas yang terlalu rendah, sehingga memastikan aplikasi tidak mencapai batas selama kasus penggunaan yang wajar.
Konfigurasi universal: Batas berlaku untuk semua proses aplikasi di perangkat, termasuk aplikasi bawaan. Tidak ada daftar yang diizinkan untuk mengecualikan aplikasi tertentu dari batas ini.
Mengubah konfigurasi
Untuk mengubah batas di seluruh sistem, ikuti langkah-langkah berikut:
- Ubah
/vendor/etc/memory-limiter-config.xml. - Mulai ulang perangkat atau mulai ulang
system_serveragar perubahan dapat diterapkan.
Perintah shell
Perintah am memory-limiter memungkinkan Anda dan developer berinteraksi dengan
layanan saat runtime untuk pengembangan dan pengujian:
am memory-limiter <SUB-COMMAND>status
Sub-perintah status melaporkan status operasional 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 sedang aktif memantau proses.
visibleMemdannotVisibleMem- Tunjukkan batas memori absolut yang dihitung untuk setiap status.
events- Jumlah proses yang telah melampaui batasnya.
processes- Jumlah proses yang dipantau.
abaikan
Sub-perintah ignore mengecualikan UID atau semua proses untuk sementara agar tidak dibatasi. Tindakan ini berguna untuk pengujian performa atau saat mengizinkan aplikasi tertentu melampaui batasnya.
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
manual
Sub-perintah manual menggantikan batas yang dihitung untuk proses tertentu
(berdasarkan ID proses, atau PID) dengan nilai absolut kustom dalam megabyte (MB):
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
Penggantian manual hanya berlaku untuk siklus proses. Jika proses dimulai ulang, proses akan kembali ke batas default berdasarkan statusnya.