Bagaimana saya dapat menemukan memori yang digunakan pada aplikasi Android saya, secara terprogram?
Saya harap ada cara untuk melakukannya. Plus, bagaimana cara mendapatkan memori bebas telepon juga?
java
android
memory
memory-management
Andrea Baccega
sumber
sumber
Jawaban:
Perhatikan bahwa penggunaan memori pada sistem operasi modern seperti Linux adalah bidang yang sangat rumit dan sulit dipahami. Bahkan kemungkinan Anda benar-benar menafsirkan angka apa pun yang Anda dapatkan sangat rendah. (Cukup banyak setiap kali saya melihat nomor penggunaan memori dengan insinyur lain, selalu ada diskusi panjang tentang apa yang sebenarnya berarti bahwa hanya menghasilkan kesimpulan yang samar-samar.)
Catatan: kami sekarang memiliki dokumentasi yang jauh lebih luas tentang Mengelola Memori Aplikasi Anda yang mencakup banyak materi di sini dan lebih mutakhir dengan keadaan Android.
Hal pertama adalah mungkin membaca bagian terakhir dari artikel ini yang memiliki beberapa diskusi tentang bagaimana memori dikelola di Android:
Perubahan API Layanan dimulai dengan Android 2.0
Sekarang
ActivityManager.getMemoryInfo()
adalah API tingkat tertinggi kami untuk melihat penggunaan memori secara keseluruhan. Ini sebagian besar ada untuk membantu aplikasi mengukur seberapa dekat sistem tidak memiliki memori lebih untuk proses latar belakang, sehingga perlu mulai membunuh proses yang diperlukan seperti layanan. Untuk aplikasi Java murni, ini seharusnya tidak banyak berguna, karena batas heap Java ada sebagian untuk menghindari satu aplikasi dari dapat menekankan sistem ke titik ini.Menuju level yang lebih rendah, Anda dapat menggunakan Debug API untuk mendapatkan informasi level kernel mentah tentang penggunaan memori: android.os.Debug.MemoryInfo
Catatan dimulai dengan 2.0 ada juga API
ActivityManager.getProcessMemoryInfo
,, untuk mendapatkan informasi ini tentang proses lain: ActivityManager.getProcessMemoryInfo (int [])Ini mengembalikan struktur MemoryInfo tingkat rendah dengan semua data ini:
Tapi seperti apa perbedaan antara
Pss
,PrivateDirty
danSharedDirty
... baik sekarang menyenangkan dimulai.Banyak memori di Android (dan sistem Linux pada umumnya) sebenarnya dibagi di banyak proses. Jadi berapa banyak memori yang digunakan suatu proses benar-benar tidak jelas. Tambahkan paging keluar ke disk (apalagi swap yang tidak kita gunakan pada Android) dan itu bahkan kurang jelas.
Jadi jika Anda mengambil semua RAM fisik yang benar-benar dipetakan ke dalam setiap proses, dan menambahkan semua proses, Anda mungkin akan berakhir dengan angka yang jauh lebih besar daripada total RAM yang sebenarnya.
The
Pss
nomor adalah metrik ini menghitung kernel yang memperhitungkan berbagi memori akun - pada dasarnya setiap halaman RAM dalam proses skala oleh rasio jumlah proses lain juga menggunakan halaman tersebut. Dengan cara ini Anda dapat (secara teori) menambahkan pss di semua proses untuk melihat total RAM yang mereka gunakan, dan membandingkan pss antara proses untuk mendapatkan gambaran kasar tentang bobot relatif mereka.Metrik menarik lainnya di sini adalah
PrivateDirty
, yang pada dasarnya adalah jumlah RAM di dalam proses yang tidak dapat di-paging ke disk (tidak didukung oleh data yang sama pada disk), dan tidak dibagi dengan proses lain. Cara lain untuk melihat ini adalah RAM yang akan tersedia untuk sistem ketika proses itu hilang (dan mungkin dengan cepat dimasukkan ke dalam cache dan penggunaan lainnya).Cukup banyak SDK API untuk ini. Namun ada lebih banyak yang dapat Anda lakukan sebagai pengembang dengan perangkat Anda.
Menggunakan
adb
, ada banyak informasi yang bisa Anda dapatkan tentang penggunaan memori sistem yang sedang berjalan. Yang umum adalah perintahadb shell dumpsys meminfo
yang akan memuntahkan banyak informasi tentang penggunaan memori dari setiap proses Java, yang berisi info di atas serta berbagai hal lainnya. Anda juga dapat menempel pada nama atau pid dari satu proses untuk melihat, misalnyaadb shell dumpsys meminfo system
memberi saya proses sistem:Bagian atas adalah yang utama, di mana
size
ukuran total dalam ruang alamat heap tertentu,allocated
adalah kb dari alokasi aktual yang menurut heap,free
adalah sisa kb yang bebas dari heap untuk alokasi tambahan, danpss
danpriv dirty
sama seperti dibahas sebelumnya khusus untuk halaman yang terkait dengan masing-masing tumpukan.Jika Anda hanya ingin melihat penggunaan memori di semua proses, Anda dapat menggunakan perintah
adb shell procrank
. Output dari ini pada sistem yang sama terlihat seperti:Di sini kolom
Vss
danRss
pada dasarnya berisik (ini adalah ruang alamat langsung dan penggunaan RAM dari suatu proses, di mana jika Anda menambahkan penggunaan RAM di seluruh proses Anda mendapatkan jumlah yang sangat besar).Pss
seperti yang kita lihat sebelumnya, danUss
sekarangPriv Dirty
.Hal yang menarik untuk diperhatikan di sini:
Pss
danUss
sedikit (atau lebih dari sedikit) berbeda dari apa yang kami lihatmeminfo
. Mengapa demikian? Well procrank menggunakan mekanisme kernel yang berbeda untuk mengumpulkan datanyameminfo
, dan mereka memberikan hasil yang sedikit berbeda. Mengapa demikian? Jujur saya tidak tahu. Saya percayaprocrank
mungkin yang lebih akurat ... tapi sungguh, ini hanya meninggalkan titik: "ambil info memori yang Anda dapatkan dengan sebutir garam; sering kali butir yang sangat besar."Akhirnya ada perintah
adb shell cat /proc/meminfo
yang memberikan ringkasan dari keseluruhan penggunaan memori sistem. Ada banyak data di sini, hanya beberapa angka pertama yang layak dibahas (dan yang tersisa hanya dimengerti oleh beberapa orang, dan pertanyaan saya tentang beberapa orang itu tentang mereka sering menghasilkan penjelasan yang saling bertentangan):MemTotal
adalah jumlah total memori yang tersedia untuk kernel dan ruang pengguna (seringkali kurang dari RAM fisik sebenarnya dari perangkat, karena sebagian dari RAM itu diperlukan untuk radio, buffer DMA, dll).MemFree
adalah jumlah RAM yang tidak digunakan sama sekali. Jumlah yang Anda lihat di sini sangat tinggi; biasanya pada sistem Android ini hanya beberapa MB, karena kami mencoba menggunakan memori yang tersedia untuk menjaga proses tetap berjalanCached
adalah RAM yang digunakan untuk cache sistem file dan hal-hal lain semacam itu. Sistem khas perlu memiliki 20MB atau lebih untuk ini agar tidak masuk ke kondisi halaman yang buruk; Android out of memory killer disetel untuk sistem tertentu untuk memastikan bahwa proses latar belakang dimatikan sebelum RAM yang di-cache dikonsumsi terlalu banyak oleh mereka untuk menghasilkan paging seperti itu.sumber
Ya, Anda dapat memperoleh informasi memori secara terprogram dan memutuskan apakah akan melakukan pekerjaan yang intensif memori.
Dapatkan Ukuran VM Heap dengan menelepon:
Dapatkan Memori VM yang dialokasikan dengan menelepon:
Dapatkan VM Heap Size Limit dengan menelepon:
Dapatkan Memori Alokasi Asli dengan menelepon:
Saya membuat aplikasi untuk mengetahui perilaku OutOfMemoryError dan memonitor penggunaan memori.
https://play.google.com/store/apps/details?id=net.coocood.oomresearch
Anda bisa mendapatkan kode sumber di https://github.com/coocood/oom-research
sumber
Ini adalah pekerjaan yang sedang berjalan, tapi ini yang saya tidak mengerti:
Mengapa PID tidak dipetakan ke hasil di activityManager.getProcessMemoryInfo ()? Jelas Anda ingin menjadikan data yang dihasilkan bermakna, jadi mengapa Google membuatnya sangat sulit untuk menghubungkan hasil? Sistem saat ini bahkan tidak berfungsi dengan baik jika saya ingin memproses seluruh penggunaan memori karena hasil yang dikembalikan adalah array dari objek android.os.Debug.MemoryInfo, tetapi tidak ada objek yang benar-benar memberi tahu Anda apa yang terkait dengan pids. Jika Anda hanya memasukkan array dari semua tawaran, Anda tidak akan dapat memahami hasilnya. Seperti yang saya pahami penggunaannya, tidak ada artinya untuk melewatkan lebih dari satu pid pada satu waktu, dan kemudian jika itu masalahnya, mengapa membuatnya jadi activityManager.getProcessMemoryInfo () hanya membutuhkan array int?
sumber
Hackbod's adalah salah satu jawaban terbaik di Stack Overflow. Ini menyoroti subjek yang sangat tidak jelas. Itu banyak membantu saya.
Sumber lain yang sangat membantu adalah video yang harus dilihat ini: Google I / O 2011: Manajemen memori untuk Aplikasi Android
MEMPERBARUI:
Process Stats, layanan untuk mengetahui bagaimana aplikasi Anda mengelola memori dijelaskan di posting blog Process Stats: Memahami Bagaimana Aplikasi Anda Menggunakan RAM oleh Dianne Hackborn:
sumber
Android Studio 0.8.10+ telah memperkenalkan alat yang sangat berguna yang disebut Memory Monitor .
Apa manfaatnya untuk:
Gambar 1. Memaksa acara GC (Pengumpulan Sampah) di Android Memory Monitor
Anda dapat memiliki banyak informasi bagus tentang konsumsi waktu nyata RAM aplikasi Anda dengan menggunakannya.
sumber
1) Saya rasa tidak, paling tidak dari Jawa.
2)
sumber
Kami menemukan bahwa semua cara standar untuk mendapatkan memori total dari proses saat ini memiliki beberapa masalah.
Runtime.getRuntime().totalMemory()
: hanya mengembalikan memori JVMActivityManager.getMemoryInfo()
,Process.getFreeMemory()
dan apa pun berdasarkan/proc/meminfo
- mengembalikan info memori tentang semua proses yang digabungkan (mis. android_util_Process.cpp )Debug.getNativeHeapAllocatedSize()
- menggunakanmallinfo()
yang mengembalikan informasi tentang alokasi memori yang dilakukan olehmalloc()
dan fungsi terkait saja (lihat android_os_Debug.cpp )Debug.getMemoryInfo()
- Melakukan pekerjaan tetapi terlalu lambat. Dibutuhkan sekitar 200ms pada Nexus 6 untuk satu panggilan. Kinerja overhead membuat fungsi ini tidak berguna bagi kami karena kami menyebutnya secara teratur dan setiap panggilan cukup terlihat (lihat android_os_Debug.cpp )ActivityManager.getProcessMemoryInfo(int[])
- panggilanDebug.getMemoryInfo()
internal (lihat ActivityManagerService.java )Akhirnya, kami akhirnya menggunakan kode berikut:
Ia mengembalikan metrik VmRSS . Anda dapat menemukan detail lebih lanjut di sini: satu , dua dan tiga .
PS Saya perhatikan bahwa temanya masih kekurangan potongan kode aktual dan sederhana tentang cara memperkirakan penggunaan memori pribadi dari proses jika kinerjanya bukan persyaratan penting:
sumber
Di android studio 3.0 mereka telah memperkenalkan android-profiler untuk membantu Anda memahami bagaimana aplikasi Anda menggunakan CPU, memori, jaringan, dan sumber daya baterai.
https://developer.android.com/studio/profile/android-profiler
sumber
Ada banyak jawaban di atas yang pasti akan membantu Anda tetapi (setelah 2 hari mampu dan meneliti alat memori adb) saya pikir saya dapat membantu dengan pendapat saya juga.
Seperti yang dikatakan Hackbod: Jadi, jika Anda mengambil semua RAM fisik yang benar-benar dipetakan ke dalam setiap proses, dan menambahkan semua proses, Anda mungkin akan berakhir dengan angka yang jauh lebih besar daripada total RAM yang sebenarnya. jadi tidak ada cara Anda bisa mendapatkan jumlah memori yang tepat per proses.
Tapi Anda bisa mendekatinya dengan beberapa logika..dan saya akan memberitahu caranya ..
Jadi pertama-tama Anda harus menjadi pengguna root untuk membuatnya berfungsi. Masuk ke konsol dengan hak istimewa root dengan mengeksekusi
su
dalam proses dan mendapatkannyaoutput and input stream
. Kemudianid\n
masukkan (masukkan) dalam ouputstream dan tulis untuk memproses output, Jika akan mendapatkan inputstream yang berisiuid=0
, Anda adalah pengguna root.Sekarang di sini adalah logika yang akan Anda gunakan dalam proses di atas
Ketika Anda mendapatkan ouputstream dari proses, lewati perintah Anda (procrank, dumpsys meminfo, dll ...) dengan
\n
alih - alih id dan dapatkaninputstream
dan baca, simpan aliran dalam byte [], char [] dll. Gunakan raw mentah..dan Anda selesai !!!!!izin:
Periksa apakah Anda pengguna root:
Jalankan perintah Anda dengan
su
logcat:
Ini hanya mencoba, tolong sarankan saya jika saya melewatkan sesuatu
sumber