Daemon killer memori rendah

Proses Android low memory killer daemon (lmkd) memantau status memori sistem Android yang sedang berjalan dan bereaksi terhadap tekanan memori tinggi dengan menghentikan proses yang paling tidak penting agar sistem tetap berperforma pada tingkat yang dapat diterima.

Tentang tekanan memori

Sistem Android yang menjalankan beberapa proses secara paralel dapat mengalami situasi saat memori sistem habis dan proses yang memerlukan lebih banyak memori mengalami penundaan yang signifikan. Tekanan memori, status saat sistem kehabisan memori, mengharuskan Android mengosongkan memori (untuk mengurangi tekanan) dengan membatasi atau menghentikan proses yang tidak penting, meminta proses untuk mengosongkan resource yang di-cache dan tidak penting, dan sebagainya.

Secara historis, Android memantau tekanan memori sistem menggunakan driver low memory killer (LMK) dalam kernel, mekanisme kaku yang bergantung pada nilai hardcode. Mulai kernel 4.12, driver LMK dihapus dari kernel upstream dan lmkd ruang pengguna melakukan pemantauan memori dan tugas penghentian proses.

Informasi tekanan terhenti

Android 10 dan yang lebih tinggi mendukung mode lmkd baru yang menggunakan monitor informasi jeda tekanan kernel (PSI) untuk mendeteksi tekanan memori. Patchset PSI di kernel upstream (di-backport ke kernel 4.9 dan 4.14) mengukur jumlah waktu yang tertunda karena kekurangan memori. Karena penundaan ini secara langsung memengaruhi pengalaman pengguna, penundaan ini merupakan metrik yang mudah untuk menentukan tingkat keparahan tekanan memori. Kernel upstream juga menyertakan monitor PSI yang memungkinkan proses ruang pengguna berhak istimewa (seperti lmkd) untuk menentukan nilai minimum penundaan ini dan berlangganan peristiwa dari kernel saat nilai minimum dilanggar.

Monitor PSI versus sinyal vmpressure

Karena sinyal vmpressure (yang dihasilkan oleh kernel untuk mendeteksi tekanan memori dan digunakan oleh lmkd) sering kali menyertakan banyak positif palsu, lmkd harus melakukan pemfilteran untuk menentukan apakah memori berada di bawah tekanan yang sebenarnya. Hal ini menyebabkan pengaktifan lmkd yang tidak perlu dan penggunaan resource komputasi tambahan. Penggunaan monitor PSI menghasilkan deteksi tekanan memori yang lebih akurat dan meminimalkan overhead pemfilteran.

Menggunakan monitor PSI

Untuk menggunakan monitor PSI, bukan peristiwa vmpressure, konfigurasikan properti ro.lmk.use_psi. Setelan defaultnya adalah true, sehingga PSI memantau mekanisme default deteksi tekanan memori untuk lmkd. Karena monitor PSI memerlukan dukungan kernel, kernel harus menyertakan patch backport PSI dan dikompilasi dengan dukungan PSI diaktifkan (CONFIG_PSI=y).

Kekurangan driver LMK dalam kernel

Android tidak lagi menggunakan driver LMK karena sejumlah masalah, termasuk:

  • Perangkat dengan RAM rendah harus disetel secara agresif, dan meskipun demikian, performanya akan buruk pada beban kerja dengan pagecache aktif yang didukung file besar. Performa yang buruk menyebabkan thrashing dan tidak ada kill.
  • Driver kernel LMK mengandalkan batas memori bebas, tanpa penskalaan berdasarkan tekanan memori.
  • Karena kekakuan desain, partner sering menyesuaikan driver agar dapat berfungsi di perangkat mereka.
  • Driver LMK terhubung ke API slab shrinker, yang tidak dirancang untuk operasi berat seperti menelusuri target dan menghentikannya, yang memperlambat proses vmscan.

Lmkd ruang pengguna

lmkd ruang pengguna menerapkan fungsi yang sama dengan driver dalam kernel, tetapi menggunakan mekanisme kernel yang ada untuk mendeteksi dan memperkirakan tekanan memori. Mekanisme tersebut mencakup penggunaan peristiwa vmpressure yang dihasilkan kernel atau monitor informasi tekanan macet (PSI) untuk mendapatkan notifikasi tentang tingkat tekanan memori, dan menggunakan fitur cgroup memori untuk membatasi resource memori yang dialokasikan ke setiap proses berdasarkan tingkat kepentingan proses.

Menggunakan lmkd ruang pengguna di Android 10

Di Android 9 dan yang lebih baru, ruang pengguna lmkd akan aktif jika driver LMK dalam kernel tidak terdeteksi. Karena ruang pengguna lmkd memerlukan dukungan kernel untuk cgroups memori, kernel harus dikompilasi dengan setelan konfigurasi berikut:

CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y

Strategi kill

lmkd ruang pengguna mendukung strategi penghentian berdasarkan peristiwa vmpressure atau monitor PSI, tingkat keparahannya, dan petunjuk lainnya seperti penggunaan swap. Strategi penghentian berbeda antara perangkat bermemoir rendah dan berperforma tinggi:

  • Pada perangkat dengan memori rendah, sistem harus dapat mentoleransi tekanan memori yang lebih tinggi sebagai mode operasi normal.
  • Pada perangkat berperforma tinggi, tekanan memori harus dilihat sebagai situasi abnormal dan diperbaiki sebelum memengaruhi performa secara keseluruhan.

Anda dapat mengonfigurasi strategi penghentian menggunakan properti ro.config.low_ram.

lmkd ruang pengguna juga mendukung mode lama yang membuat keputusan penghentian menggunakan strategi yang sama dengan driver LMK dalam kernel (yaitu, memori kosong dan nilai minimum cache file). Untuk mengaktifkan mode lama, tetapkan properti ro.lmk.use_minfree_levels ke true.

Mengonfigurasi lmkd

Konfigurasikan lmkd untuk perangkat tertentu menggunakan properti berikut.

Properti Gunakan Default
ro.config.low_ram Tentukan apakah perangkat adalah perangkat dengan RAM rendah atau berperforma tinggi. false
ro.lmk.use_psi Gunakan monitor PSI (bukan peristiwa vmpressure). true
ro.lmk.use_minfree_levels Gunakan memori bebas dan nilai minimum cache file untuk membuat keputusan penghentian proses (yaitu, cocokkan fungsi driver LMK dalam kernel). false
ro.lmk.low Skor oom_adj minimum untuk proses yang memenuhi syarat untuk dihentikan pada level vmpressure rendah. 1001
(dinonaktifkan)
ro.lmk.medium Skor oom_adj minimum untuk proses yang memenuhi syarat untuk dihentikan di level vmpressure sedang. 800
(layanan yang di-cache atau tidak penting)
ro.lmk.critical Skor oom_adj minimum untuk proses yang memenuhi syarat untuk dihentikan pada level vmpressure kritis. 0
(proses apa pun)
ro.lmk.critical_upgrade Aktifkan upgrade ke tingkat kritis. false
ro.lmk.upgrade_pressure mem_pressure maksimum saat level diupgrade karena sistem melakukan swap terlalu banyak. 100
(dinonaktifkan)
ro.lmk.downgrade_pressure mem_pressure minimum saat peristiwa vmpressure diabaikan karena masih ada memori kosong yang cukup. 100
(dinonaktifkan)
ro.lmk.kill_heaviest_task Menghentikan tugas yang paling berat dan memenuhi syarat (keputusan terbaik) dibandingkan tugas yang memenuhi syarat (keputusan cepat). false
ro.lmk.kill_timeout_ms Durasi dalam milidetik setelah penghentian saat tidak ada penghentian tambahan yang akan dilakukan. 0
(dinonaktifkan)
ro.lmk.debug Aktifkan log debug lmkd. false

Contoh konfigurasi perangkat:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.lmk.low=1001 \
    ro.lmk.medium=800 \
    ro.lmk.critical=0 \
    ro.lmk.critical_upgrade=false \
    ro.lmk.upgrade_pressure=100 \
    ro.lmk.downgrade_pressure=100 \
    ro.lmk.kill_heaviest_task=true

Lmkd ruang pengguna di Android 11

Android 11 meningkatkan lmkd dengan memperkenalkan strategi penghentian baru. Strategi penghentian menggunakan mekanisme PSI untuk deteksi tekanan memori yang diperkenalkan di Android 10. lmkd di Android 11 memperhitungkan tingkat penggunaan resource memori dan thrashing untuk mencegah kehabisan memori dan degradasi performa. Strategi penghentian ini menggantikan strategi sebelumnya dan dapat digunakan di perangkat berperforma tinggi dan perangkat dengan RAM rendah (Android Go).

Persyaratan kernel

Untuk perangkat Android 11, lmkd memerlukan fitur kernel berikut:

  • Menyertakan patch PSI dan mengaktifkan PSI (backport tersedia di kernel umum Android 4.9, 4.14, dan 4.19).
  • Menyertakan patch dukungan PIDFD (backport tersedia di kernel umum Android 4.9, 4.14, dan 4.19).
  • Untuk perangkat dengan RAM rendah, sertakan cgroups memori.

Kernel harus dikompilasi dengan setelan konfigurasi berikut:

CONFIG_PSI=y

Mengonfigurasi lmkd di Android 11

Strategi penghentian memori di Android 11 mendukung tombol penyesuaian dan default yang tercantum di bawah. Fitur ini berfungsi di perangkat berperforma tinggi dan perangkat dengan RAM rendah.

Properti Gunakan Default
Performa tinggi RAM rendah
ro.lmk.psi_partial_stall_ms Batas jeda PSI parsial, dalam milidetik, untuk memicu notifikasi memori rendah. Jika perangkat menerima notifikasi tekanan memori terlalu terlambat, kurangi nilai ini untuk memicu notifikasi lebih awal. Jika notifikasi tekanan memori terpicu tanpa perlu, tingkatkan nilai ini untuk membuat perangkat kurang sensitif terhadap derau. 70 200
ro.lmk.psi_complete_stall_ms Batas PSI yang terhenti sepenuhnya, dalam milidetik, untuk memicu notifikasi memori kritis. Jika perangkat menerima notifikasi tekanan memori kritis terlambat, kurangi nilai ini untuk memicu notifikasi lebih awal. Jika notifikasi tekanan memori kritis terpicu tanpa perlu, tingkatkan nilai ini agar perangkat tidak terlalu sensitif terhadap derau. 700
ro.lmk.thrashing_limit Jumlah maksimum refault set kerja sebagai persentase dari total ukuran pagecache yang didukung file. Refault set kerja di atas nilai ini berarti sistem dianggap melakukan thrashing pada pagecache-nya. Jika performa perangkat terpengaruh selama tekanan memori, kurangi nilai untuk membatasi thrashing. Jika performa perangkat dihentikan secara tidak perlu karena alasan thrashing, naikkan nilai untuk mengizinkan lebih banyak thrashing. 100 30
ro.lmk.thrashing_limit_decay Degradasi nilai minimum thrashing yang dinyatakan sebagai persentase dari nilai minimum asli yang digunakan untuk menurunkan nilai minimum saat sistem tidak pulih, bahkan setelah dihentikan. Jika thrashing yang terus-menerus menghasilkan penghentian yang tidak perlu, kurangi nilainya. Jika respons terhadap thrashing berkelanjutan setelah penghentian terlalu lambat, tingkatkan nilainya. 10 50
ro.lmk.swap_util_max Jumlah maksimum memori yang di-swap sebagai persentase dari total memori yang dapat di-swap. Jika memori yang di-swap bertambah melebihi batas ini, berarti sistem telah menukar sebagian besar memori yang dapat di-swap dan masih berada di bawah tekanan. Hal ini dapat terjadi saat alokasi yang tidak dapat ditukar menghasilkan tekanan memori yang tidak dapat dihilangkan dengan swapping karena sebagian besar memori yang dapat ditukar sudah ditukar. Nilai defaultnya adalah 100, yang secara efektif menonaktifkan pemeriksaan ini. Jika performa perangkat terpengaruh selama tekanan memori saat penggunaan swap tinggi dan level swap bebas tidak turun ke ro.lmk.swap_free_low_percentage, kurangi nilai untuk membatasi penggunaan swap. 100 100

Tombol penyesuaian lama berikut juga berfungsi dengan strategi penghentian baru.

Properti Gunakan Default
Performa tinggi RAM rendah
ro.lmk.swap_free_low_percentage Tingkat swap bebas sebagai persentase dari total ruang swap. `lmkd` menggunakan nilai ini sebagai nilai minimum untuk menentukan kapan sistem dianggap kehabisan ruang swap. Jika `lmkd` membunuh saat ada terlalu banyak ruang dalam swap, kurangi persentasenya. Jika penghentian `lmkd` terjadi terlalu terlambat, sehingga penghentian OOM dapat terjadi, tingkatkan persentasenya. 20 10
ro.lmk.debug Tindakan ini akan mengaktifkan log debug `lmkd`. Aktifkan debug saat melakukan penyesuaian. false