Pembatas Memori

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 prosesBatas memori
PERSISTENTTidak dibatasi
PERSISTENT_UITidak dibatasi
TOPTerlihat
BOUND_TOPTerlihat
FOREGROUND_SERVICETidak terlihat
BOUND_FOREGROUND_SERVICETidak terlihat
IMPORTANT_FOREGROUNDTerlihat
IMPORTANT_BACKGROUNDTidak terlihat
TRANSIENT_BACKGROUNDTidak terlihat
BACKUPTidak terlihat
SERVICETidak terlihat
RECEIVERTidak terlihat
TOP_SLEEPINGTerlihat
HEAVY_WEIGHTTidak terlihat
HOMETidak terlihat
LAST_ACTIVITYTidak terlihat
CACHED_ACTIVITYDi-cache
CACHED_ACTIVITY_CLIENTDi-cache
CACHED_RECENTDi-cache
CACHED_EMPTYDi-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.xml

  • Konfigurasi 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:

  1. Ubah /vendor/etc/memory-limiter-config.xml.
  2. Mulai ulang perangkat atau mulai ulang system_server agar 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 status

Contoh 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.
visibleMem dan notVisibleMem
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 UID
adb 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 1234
adb 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.