Pembatas Memori

Android 17 dan yang lebih baru mendukung Pembatas Memori, yang merupakan layanan sistem yang memantau dan membatasi penggunaan memori proses aplikasi menggunakan cgroup v2 Linux. Pembatas Memori mencegah setiap aplikasi mengonsumsi memori sistem secara berlebihan, yang mengurangi tekanan memori di seluruh sistem dan mencegah penghentian proses penting secara agresif karena kehabisan memori (OOM).

Mekanisme

Pembatas Memori terintegrasi dengan Layanan Pengelola Aktivitas (AMS) untuk melacak peristiwa siklus proses dan perubahan status. Pembatas Memori menerapkan batas memori menggunakan sistem file cgroup v2 kernel Linux.

Untuk menggunakan Pembatas Memori, kernel perangkat harus mendukung cgroup v2 dan pengontrol memory. Layanan ini secara khusus mengandalkan atribut berikut:

memory.high
Batas yang dapat dilewati. Jika terlampaui, proses akan di-throttle dan kernel akan mencoba mengklaim 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 untuk menjaga aplikasi tetap dalam batas. Akibat pengeluaran dan swap, aplikasi mungkin berjalan lebih lambat.

Pada kondisi ekstrem, jika aplikasi terus mengalokasikan memori anonim dan perangkat kehabisan ruang swap, aplikasi mungkin gagal mengalokasikan memori, dan akibatnya kemungkinan akan mengalami 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 berada dalam status yang dapat menampilkan UI kepada pengguna. Saat menampilkan UI, proses mungkin diharapkan menggunakan set kerja RAM yang lebih besar, sehingga proses tersebut diberikan batas memori yang lebih besar.

  • Proses yang tidak terlihat berada dalam status yang aktif melakukan pekerjaan, tetapi tidak menggambar UI. Proses ini menggunakan memori untuk melakukan pekerjaan ini, tetapi lebih sedikit daripada yang dibutuhkan saat menampilkan UI, sehingga proses ini diberi batas yang lebih ketat.

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 yang di-cache, proses akan dibekukan, lalu diklaim kembali secara maksimal.

Saat proses melebihi batas memory.high yang ditetapkan, Pembatas Memori akan mendeteksi peristiwa tersebut dan dapat memicu tindakan proses debug, seperti mengambil profil memori atau mencatat anomali ke statsd.

Konfigurasi

Konfigurasi Pembatas Memori menggunakan file XML yang terletak 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 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 kumpulan batas; layanan akan memilih kecocokan terbaik berdasarkan RAM yang tersedia di perangkat. Semua nilai memori ditentukan dalam unit 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 minimum yang diperlukan agar kumpulan batas ini 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 swap (memory.swap.max) yang diizinkan untuk proses yang terlihat.
swapNotVisible
Batas swap (memory.swap.max) yang diizinkan untuk proses yang tidak terlihat.

Panduan batas memori perangkat

Saat mengonfigurasi batas memori untuk perangkat, pertimbangkan panduan berikut:

  • Sesuaikan 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 yang telah diinstal sebelumnya. Tidak ada daftar yang diizinkan untuk mengecualikan aplikasi tertentu dari batas ini.

Memodifikasi 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 aktif memantau proses.
visibleMem dan notVisibleMem
Menunjukkan batas memori absolut yang dihitung untuk setiap status.
events
Jumlah proses yang telah melebihi batasnya.
processes
Jumlah proses yang dipantau.

ignore

Sub-perintah ignore untuk sementara mengecualikan UID atau semua proses agar tidak dibatasi. Tindakan ini berguna untuk pengujian performa atau saat mengizinkan aplikasi tertentu melebihi 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 mengganti 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.