Thread dan memori

Setiap kali aplikasi Anda membuat thread baru, sistem operasi harus mengalokasikan memori untuk mendukungnya. Meskipun thread umumnya dianggap "ringan" dibandingkan dengan proses penuh, biaya memorinya tidak nol. Thread yang bocor adalah cara yang sangat umum untuk membocorkan memori di Android.

Biaya thread

Saat thread dibuat di Android, dua komponen utama menggunakan memori:

  1. Native Stack: Library pthread mengalokasikan stack untuk thread guna menyimpan variabel lokal dan memanggil frame. Di Android, ini biasanya 1 MB secara default.
  2. Struktur JVM/Kernel Internal: ART dan kernel Linux harus mengalokasikan struktur data (seperti pthread_internal_t dan java.lang.Thread objek) untuk melacak dan mengelola thread.

Memori stack dan mmap

Penting untuk memahami bahwa Android mengalokasikan stack native 1 MB menggunakan mmap dengan flag MAP_ANONYMOUS | MAP_NORESERVE.

Artinya, OS mencadangkan ruang alamat memori virtual sebesar 1 MB, tetapi tidak langsung mengalokasikan RAM fisik sebesar 1 MB. Memori fisik hanya dialokasikan (di-page in) saat thread benar-benar menjalankan kode dan mendorong data ke stack. Thread yang tidak melakukan apa pun akan menggunakan RAM fisik yang sangat kecil untuk stack-nya.

Latihan interaktif: thread yang bocor

Kita akan menggunakan aplikasi contoh MemoryLab untuk mengamati apa yang terjadi saat aplikasi membuat ratusan thread tidak aktif.

1. Peluncuran dan dasar pengukuran

Luncurkan aplikasi dan ambil pembacaan memori dasar:

adb shell am start -W -n com.android.memorylab/.MainActivity
adb shell dumpsys meminfo -s com.android.memorylab

Lihat baris Stack dan Native Heap dalam output. Kemungkinan akan kecil.

2. Membuat 100 thread

Ketuk tombol Create 100 Threads. Aplikasi akan membuat 100 thread baru. Untuk memastikan memori stack benar-benar di-page in ke RAM fisik (sehingga kita dapat melihatnya di alat kita), setiap thread mengalokasikan dan menulis ke array 10 KB kecil di stack-nya sebelum mulai menunggu.

Jalankan perintah meminfo lagi saat thread aktif:

adb shell dumpsys meminfo -s com.android.memorylab

Hasil:

Bandingkan output baru dengan dasar pengukuran Anda. Anda akan melihat peningkatan signifikan saat thread aktif:

  • Stack: Meningkat sebesar satu megabyte atau lebih. Ini mewakili halaman fisik yang dialokasikan untuk 100 stack thread (masing-masing menyentuh setidaknya 10 KB).
  • Native Heap / Private Other: Meningkat karena struktur pthread internal yang dialokasikan oleh sistem untuk setiap thread.

Untuk membersihkan, ketuk tombol Destroy All Threads.

3. Melihat thread di Perfetto

Perfetto sangat baik untuk melacak siklus proses dan jumlah thread dari waktu ke waktu.

Screenshot UI Perfetto yang menampilkan jalur penghitung dengan jumlah
thread aktif, serta thread yang dimulai dan keluar di aplikasi memorylab

PerfettoSQL untuk analisis thread

Anda dapat membuat kueri rekaman aktivitas untuk menghitung dengan tepat berapa banyak thread yang dibuat oleh aplikasi:

SELECT p.name AS process_name, COUNT(t.id) as thread_count
FROM thread t JOIN process p USING (upid)
WHERE p.name = 'com.android.memorylab' AND t.name LIKE 'LeakedThread-%';

Kueri seperti ini dapat digunakan untuk membuat jalur debug dengan penghitung seperti yang ditunjukkan dalam screenshot.


← Kode aplikasi | ↑ Atas | Lokalitas →