Proses aplikasi di Android tidak ada secara terpisah. Aplikasi sering kali mengandalkan layanan yang disediakan oleh aplikasi lain atau sistem itu sendiri. Saat satu proses terhubung ke proses lain melalui Pengikatan Layanan, proses tersebut akan membuat dependensi yang berdampak besar pada cara framework Android mengelola memori.
Status proses dan skor OOM
Framework Android menggunakan Status Proses untuk melacak pentingnya setiap
proses yang sedang berjalan. Status ini kemudian digunakan oleh OomAdjuster untuk menetapkan nilai
Penyesuaian Skor OOM (oom_score_adj), yang berkisar dari -1000 hingga 1000.
oom_score_adj yang lebih rendah berarti proses lebih penting dan lebih kecil kemungkinannya untuk
dihentikan oleh Low Memory Killer (LMK).
Status proses umum
Tabel berikut menunjukkan beberapa status proses yang paling umum dan nilai oom_score_adj yang biasanya. Untuk daftar lengkap dan terbaru, lihat
android.app.ActivityManager dan com.android.server.am.psc.Constants dalam
kode sumber Android.
| Status Proses (Singk.) | Deskripsi | oom_score_adj Standar |
|---|---|---|
| PER (Persisten) | Proses sistem yang harus selalu berjalan (misalnya, Telepon). | -800 |
| TOP | Proses yang saat ini berinteraksi dengan pengguna. | 0 |
| VIS (Terlihat) | Proses memiliki aktivitas yang terlihat (misalnya, di belakang dialog transparan). | 100 |
| PERC (Terlihat) | Proses latar belakang yang diketahui pengguna (misalnya, pemutaran musik). | 200 |
| FGS | Proses yang menghosting Layanan Latar Depan. | 0 hingga 200 (bervariasi) |
| BTOP (Bound Top) | Proses yang terikat oleh aplikasi TOP. | 100 |
| BFGS | Layanan Latar Depan Terikat (biasanya terikat sistem). | 0 |
| SEBELUMNYA (Previous) | Proses terakhir yang dilakukan pengguna sebelum proses saat ini. | 700 |
| DI-CACHE | Aplikasi latar belakang yang dapat dihentikan dengan aman. | 900 hingga 999 |
Dampak binding layanan
Saat proses klien (misalnya, aplikasi dalam status TOP) terikat ke layanan dalam
proses server, proses server sering kali mewarisi prioritas yang lebih tinggi. Hal ini memastikan layanan tetap tersedia selama klien membutuhkannya.

Mengontrol pewarisan dengan flag BIND
Pewarisan adalah perilaku default saat menggunakan Context.BIND_AUTO_CREATE.
Namun, developer dapat mengontrol pengaruh pengikatan terhadap
pentingnya proses target menggunakan berbagai tanda di bindService().
Flag BIND utama untuk skor OOM
Flag berikut paling relevan saat mengelola tekanan memori di seluruh sistem:
BIND_AUTO_CREATE: Flag yang paling umum. Hal ini memastikan proses layanan dimulai dan tetap aktif selama pengikatan ada. Secara default, opsi ini juga meningkatkan prioritas proses server agar sesuai dengan klien.BIND_NOT_FOREGROUND: Mencegah proses layanan target dinaikkan ke prioritas penjadwalan latar depan (prioritas CPU). Namun, masih memungkinkan prioritas memori (oom_score_adj) ditingkatkan. Hal ini berguna untuk pekerjaan di latar belakang yang tidak boleh bersaing dengan UI untuk siklus CPU, tetapi harus tetap dilindungi agar tidak dihentikan.BIND_WAIVE_PRIORITY: Flag yang sangat kuat yang menginstruksikan sistem untuk tidak memengaruhi prioritas penjadwalan atau pengelolaan memori dari proses target. Proses layanan akan dikelola seolah-olah merupakan proses latar belakang biasa dalam daftar LRU, sehingga memenuhi syarat untuk diakhiri karena kehabisan memori (OOM) meskipun terikat.BIND_ABOVE_CLIENT: Menunjukkan bahwa layanan lebih penting daripada aplikasi klien itu sendiri. Saat sistem perlu merebut kembali memori, sistem akan lebih memilih menghentikan aplikasi klien sebelum menghentikan layanan terikat. Metode ini "lebih kuat" daripadaBIND_AUTO_CREATEkarena memberikan lapisan perlindungan tambahan untuk layanan dengan mengorbankan klien.BIND_NOT_PERCEPTIBLE: Menurunkan kepentingan layanan target ke bawah levelPERCEPTIBLE, sehingga sistem dapat merebut kembali memorinya untuk menyediakan ruang bagi proses yang lebih penting dan dapat dirasakan pengguna.
Langsung: mengamati efek pengikatan
Kita akan menggunakan aplikasi MemoryLab untuk menunjukkan cara binding dari aplikasi
TOP memengaruhi status proses terpisah.
1. Meluncurkan MemoryLab
Perintah berikut meluncurkan aplikasi. Setelah terbuka, pastikan aplikasi tetap di latar depan (jangan tekan tombol Beranda atau beralih aplikasi dulu).
adb shell am start -n com.android.memorylab/.MainActivity
2. Mengidentifikasi proses
Periksa status proses sebelum mengikat. MemoryLab menjalankan UI utamanya dalam satu proses dan memiliki RemoteService yang berjalan dalam proses :remote.
adb shell dumpsys activity processes com.android.memorylab
Cuplikan contoh output:
Process OOM control (154 total, non-act at 7, non-svc at 7):
Proc #0: fg T/A/TOP LCMNFUATI t: 0 13470:com.android.memorylab/u0a417 (top-activity)
oom: max=1001 curRaw=0 setRaw=0 cur=0 set=0
state: cur=TOP set=TOP lastRss=0.00 lastCachedRss=0.00
Anda akan melihat proses utama com.android.memorylab dalam status TOP. Proses
:remote belum dimulai.
3. Binding pemicu
Kirim siaran ke aplikasi untuk memicu pengikatan layanan:
adb shell am broadcast -a com.android.memorylab.LEAK_BINDER
4. Mengamati status yang ditinggikan
Periksa kembali status proses:
adb shell dumpsys activity processes | grep -A 10 "com.android.memorylab"
Cuplikan contoh output:
Proc # 1: vis F/ /BTOP ---NFUATI t: 0 13560:com.android.memorylab:remote/u0a417 (service)
com.android.memorylab/.RemoteService<=Proc{13470:com.android.memorylab/u0a417}
oom: max=1001 curRaw=100 setRaw=100 cur=100 set=100
state: cur=BTOP set=BTOP lastRss=0.00 lastCachedRss=0.00
Proses :remote kini berjalan dan dalam status BTOP (Bound TOP) dengan
oom_score_adj sebesar 100. Hal ini jauh lebih terlindungi daripada layanan latar belakang biasa (yang akan berada di 500 atau lebih tinggi). Notasi
<=Proc{...} menunjukkan proses mana yang bertanggung jawab atas peningkatan prioritas ini.
5. Kirim ke latar belakang
Tekan tombol HOME di perangkat. Periksa kembali statusnya:
adb shell dumpsys activity processes | grep -A 10 "com.android.memorylab"
Cuplikan contoh output:
Proc # 2: prev b/ /LAST --------I t: 0 13560:com.android.memorylab:remote/u0a417 (service)
com.android.memorylab/.RemoteService<=Proc{13470:com.android.memorylab/u0a417}
oom: max=1001 curRaw=700 setRaw=700 cur=700 set=700
state: cur=LAST set=LAST lastRss=0.00 lastCachedRss=0.00
Proc # 1: prev b/ /LAST --------I t: 0 13470:com.android.memorylab/u0a417 (previous)
oom: max=1001 curRaw=700 setRaw=700 cur=700 set=700
state: cur=LAST set=LAST lastRss=209MB lastCachedRss=0.00
Sekarang kedua proses telah beralih ke status prioritas yang lebih rendah (PREV /
oom_score_adj 700), karena proses klien tidak lagi TOP. (Catatan:
LAST dalam dump status merujuk pada status internal LAST_ACTIVITY, yang
dipetakan ke PREV dalam ringkasan tingkat tinggi).
Menganalisis dengan procstats
Alat procstats memberikan tampilan historis dari status ini.
# View stats for MemoryLab over the last hour
adb shell dumpsys procstats --hours 1 com.android.memorylab
Cuplikan contoh output:
* com.android.memorylab / u0a417 / v37:
* Prc com.android.memorylab / u0a417 / v37:
TOTAL: 0.89% (0.00-0.00-0.00/0.00-0.00-0.00/210MB-210MB-210MB over 1)
Top: 0.89% (0.00-0.00-0.00/0.00-0.00-0.00/210MB-210MB-210MB over 1)
* Prc com.android.memorylab:remote / u0a417 / v37:
TOTAL: 0.19%
Bnd Top: 0.19%
Di sini, Bnd Top menunjukkan persentase waktu yang dihabiskan proses jarak jauh
untuk terikat oleh aplikasi dalam status TOP.
Merekam dan menganalisis binding dengan Perfetto
Meskipun dumpsys memberi Anda ringkasan, Perfetto memungkinkan Anda melihat momen pasti saat pengikatan terjadi dan bagaimana perubahan skor OOM secara real-time.
1. Merekam aktivitas
Gunakan konfigurasi yang mencakup linux.process_stats dan kategori pelacakan am:
adb shell perfetto -c - --txt -o /data/misc/perfetto-traces/service_bindings.perfetto-trace <<EOF
buffers: { size_kb: 65536 }
data_sources: {
config {
name: "linux.process_stats"
process_stats_config { proc_stats_poll_ms: 100 }
}
}
data_sources: {
config {
name: "linux.ftrace"
ftrace_config { ftrace_events: "am/am_proc_bound" }
}
}
duration_ms: 15000
EOF
2. Transisi skor OOM kueri
Dengan PerfettoSQL, Anda dapat melihat bagaimana perubahan skor OOM proses jarak jauh relatif terhadap proses UI:
SELECT ts, p.name, value AS oom_score_adj
FROM counter c
JOIN process_counter_track t ON c.track_id = t.id
JOIN process p USING (upid)
WHERE p.name LIKE 'com.android.memorylab%'
AND t.name = 'oom_score_adj'
ORDER BY ts;
3. Mengidentifikasi peristiwa pengikatan
Untuk melihat secara persis kapan dependensi pengikatan dibuat dan proses mana yang memulainya, gunakan kueri ini:
SELECT
s.ts,
p.name AS process_name,
t.name AS thread_name,
s.name AS slice_name
FROM slice s
JOIN thread_track tt ON s.track_id = tt.id
JOIN thread t USING (utid)
JOIN process p USING (upid)
WHERE s.name LIKE 'bindService:{com.android.memorylab%';
Binding sistem ke aplikasi
Sistem Android itu sendiri sering kali terikat ke layanan di aplikasi pihak ketiga untuk menyediakan fungsi inti. Sering kali, tujuan binding ini adalah pengurangan latensi. Dengan menjaga proses tetap aktif dan dalam memori, sistem menghindari overhead yang mahal dari "cold start" (memuat APK, menginisialisasi runtime, dan membuat objek Aplikasi) saat interaksi pengguna yang penting terjadi. Binding lain ada untuk mencegah cold start yang sering terjadi pada aplikasi yang perlu menangani aliran peristiwa latar belakang.
Berikut beberapa contoh dunia nyata yang dapat Anda amati di perangkat biasa:
VoiceInteractor
Pengguna mengharapkan asisten digital disematkan di OS ponsel mereka, dapat dipanggil secara instan dengan hotword yang diucapkan atau gestur input cepat, dan interaksi yang lancar dan mulus.
Saat pemicu asisten terjadi (seperti kata cepat "OK Google" di ponsel Google Pixel), asisten digital harus merespons secara instan. Untuk memastikan hal ini, system_server mempertahankan pengikatan permanen ke layanan interaksi suara yang dipilih oleh pengguna.

Jika Anda memeriksa status proses (misalnya, menggunakan dumpsys activity processes), Anda mungkin melihat proses seperti com.google.android.googlequicksearchbox:interactor dalam status BFGS (Layanan Latar Depan Terikat), yang tetap aktif dengan binding dari system_server (UID 1000).
NotificationListenerService
Untuk beberapa binding sistem ke aplikasi, tujuannya bukan latensi, melainkan mencegah cold start yang sering.
NotificationListenerService,
layanan yang menerima panggilan dari sistem saat notifikasi baru diposting
atau dihapus, adalah contoh utama. Pengguna smartphone biasa dapat menerima ratusan notifikasi sepanjang hari. Jika sistem melepaskan binding dari pemroses notifikasi, proses aplikasi tersebut kemungkinan akan masuk ke status di-cache dan dapat dihentikan oleh LMK.
Saat notifikasi berikutnya tiba - mungkin beberapa detik kemudian - sistem akan dipaksa untuk melakukan cold start pada proses aplikasi lagi hanya untuk mengirimkan peristiwa tersebut. Siklus penghentian dan cold start yang konstan ini akan menggunakan CPU dan baterai yang jauh lebih banyak daripada sekadar menjaga proses tetap terikat dan aktif di latar belakang.
"Layar -1" peluncur (feed berita)
Aplikasi Peluncur Modern biasanya menggabungkan fungsi navigasi inti (ikon beranda dan widget) dengan feed berita yang tersedia di salah satu layar peluncur dan terintegrasi dengan lancar dengan UX Peluncur. Feed berita dapat disediakan oleh aplikasi lain. Misalnya, di Google Pixel, Peluncur terintegrasi dengan feed yang disediakan oleh aplikasi Google.
Saat Anda menggeser ke kiri di layar utama untuk melihat feed berita, transisinya harus lancar. Peluncur mencapai hal ini dengan mengikat ke antarmuka layanan di aplikasi yang menyediakan feed berita, dan mempertahankan pengikatan tersebut selama peluncur aktif. Hal ini membuat konten feed dirender dan siap di memori meskipun Anda tidak melihatnya.
Contoh umum lainnya
- Peluncur (HOME_APP_ADJ): Aplikasi peluncur (Layar utama) memiliki slot khusus sendiri dalam daftar prioritas. Meskipun tidak selalu terikat oleh layanan, ID ini diberi nilai
HOME_APP_ADJ(biasanya 600). Sistem lebih memilih untuk menjaga agar peluncur tetap aktif, karena pengguna sering kembali ke peluncur. Faktanya, sistem lebih memilih untuk menghentikan aplikasi yang digunakan sebelumnya (PREV_APP_ADJ = 700) daripada menghentikan peluncur, karena menghentikan peluncur akan menghasilkan pengalaman pengguna yang lambat saat keluar dari aplikasi karena pengguna harus menunggu peluncur di-cold start. - Editor Metode Input (IME): Saat Anda mengetik, sistem akan terikat ke aplikasi keyboard pilihan Anda (misalnya, Gboard). Hal ini membuat proses keyboard dalam status yang lebih tinggi meskipun keyboard disembunyikan untuk sementara. Hal ini memastikan keyboard dapat muncul kembali secara instan saat Anda mengetuk kolom teks lain.
- Pembayaran NFC: Saat Anda menyentuhkan ponsel untuk membayar, sistem akan terikat ke layanan pembayaran NFC (misalnya, Google Wallet). Transaksi ini sering kali memiliki persyaratan real-time yang ketat dari terminal penjual. Jika aplikasi pembayaran harus melakukan cold start, transaksi dapat mengalami waktu tunggu habis dan gagal.
Kompromi dan penurunan performa
Meskipun binding diperlukan untuk performa dan kebenaran, binding berdampak pada kondisi memori sistem.
- Berkurangnya Fleksibilitas: Setiap proses terikat adalah proses yang tidak dapat dihentikan dengan mudah oleh LMK. Tindakan ini mengurangi "penyangga" proses yang di-cache yang dapat digunakan sistem untuk mengosongkan memori saat tertekan.
- Memperburuk Jurang Performa: Jika terlalu banyak proses yang terikat, sistem mungkin tidak memiliki proses latar belakang yang dapat dihentikan. Saat tekanan memori meningkat, sistem akan "turun dari tebing performa" jauh lebih cepat, karena sistem dipaksa untuk mengakhiri proses yang lebih penting atau meng-thrash cache halaman.
← Lokalitas | ↑ Naik | Di seluruh sistem →