Bagaimana Anda secara terprogram mendeteksi ukuran tumpukan aplikasi yang tersedia untuk aplikasi Android?
Saya mendengar ada fungsi yang melakukan ini di versi SDK yang lebih baru. Bagaimanapun, saya mencari solusi yang berfungsi untuk 1,5 dan ke atas.
android
memory
heap
heap-memory
hpique
sumber
sumber
Jawaban:
Ada dua cara untuk memikirkan frasa "ukuran tumpukan aplikasi Anda":
Berapa banyak tumpukan yang bisa digunakan aplikasi saya sebelum kesalahan yang sulit dipicu? Dan
Berapa banyak tumpukan yang harus digunakan aplikasi saya, mengingat kendala dari versi OS Android dan perangkat keras dari perangkat pengguna?
Ada metode berbeda untuk menentukan masing-masing di atas.
Untuk item 1 di atas:
maxMemory()
yang dapat dipanggil (misalnya, dalam
onCreate()
metode aktivitas utama Anda ) sebagai berikut:Metode ini memberi tahu Anda berapa banyak total byte tumpukan yang diizinkan untuk digunakan oleh aplikasi Anda .
Untuk item 2 di atas:
getMemoryClass()
yang dapat dipanggil sebagai berikut:
Metode ini memberi tahu Anda kira-kira berapa megabita tumpukan yang harus digunakan aplikasi Anda jika ingin menghormati batas-batas perangkat saat ini dengan benar, dan tentang hak-hak aplikasi lain untuk berjalan tanpa dipaksa berulang kali ke dalam siklus
onStop()
/onResume()
karena mereka kasar. keluar dari memori sementara aplikasi gajah Anda mandi di jacuzzi Android.Perbedaan ini tidak terdokumentasi dengan jelas, sejauh yang saya tahu, tetapi saya telah menguji hipotesis ini pada lima perangkat Android yang berbeda (lihat di bawah) dan telah mengkonfirmasi untuk kepuasan saya sendiri bahwa ini adalah interpretasi yang benar.
Untuk versi stok Android,
maxMemory()
biasanya akan mengembalikan sekitar jumlah megabyte yang sama seperti yang ditunjukkan dalamgetMemoryClass()
(yaitu, sekitar satu juta kali nilai terakhir).Satu-satunya situasi (yang saya ketahui) di mana kedua metode dapat menyimpang adalah pada perangkat yang di-rooting yang menjalankan versi Android seperti CyanogenMod, yang memungkinkan pengguna untuk secara manual memilih seberapa besar ukuran heap yang diperbolehkan untuk setiap aplikasi. Dalam CM, misalnya, opsi ini muncul di bawah "Pengaturan CyanogenMod" / "Kinerja" / "VM heap size".
CATATAN: HATI-HATI YANG MENGATUR NILAI INI SECARA MANUAL AKAN DAPAT MENYESUAIKAN SISTEM ANDA, TERUTAMA jika Anda memilih nilai yang lebih kecil dari normal untuk perangkat Anda.
Berikut ini adalah hasil pengujian saya yang menunjukkan nilai yang dikembalikan oleh
maxMemory()
dangetMemoryClass()
untuk empat perangkat berbeda yang menjalankan CyanogenMod, menggunakan dua nilai tumpukan (yang diatur secara manual) untuk masing-masing:Selain yang di atas, saya menguji pada tablet Novo7 Paladin yang menjalankan Ice Cream Sandwich. Ini pada dasarnya adalah versi stok ICS, kecuali bahwa saya telah melakukan rooting tablet melalui proses sederhana yang tidak menggantikan seluruh OS, dan khususnya tidak menyediakan antarmuka yang akan memungkinkan ukuran tumpukan disesuaikan secara manual.
Untuk perangkat itu, berikut hasilnya:
Juga (per Kishore dalam komentar di bawah):
Dan (per komentar aliasuppi):
Per komentar dari cmcromance:
Dan (per komentar Tencent):
Perangkat lain
Saya belum menguji kedua metode ini menggunakan android khusus: largeHeap = "true" opsi manifes yang tersedia sejak Honeycomb, tetapi berkat cmcromance dan tencent kami memiliki beberapa contoh nilai largeHeap, seperti yang dilaporkan di atas.
Harapan saya (yang tampaknya didukung oleh angka-angka besar di atas) adalah bahwa opsi ini akan memiliki efek yang mirip dengan mengatur tumpukan secara manual melalui OS yang di-rooting - yaitu, itu akan meningkatkan nilai
maxMemory()
saat meninggalkangetMemoryClass()
sendiri. Ada metode lain, getLargeMemoryClass (), yang menunjukkan berapa banyak memori yang diperbolehkan untuk aplikasi menggunakan pengaturan largeHeap. Dokumentasi untuk getLargeMemoryClass () menyatakan, "sebagian besar aplikasi seharusnya tidak membutuhkan jumlah memori ini, dan sebaliknya harus tetap dengan batas getMemoryClass ()."Jika saya menebak dengan benar, maka menggunakan opsi itu akan memiliki manfaat yang sama (dan bahaya) seperti menggunakan ruang yang disediakan oleh pengguna yang menaikkan tumpukan melalui OS yang di-root (yaitu, jika aplikasi Anda menggunakan memori tambahan, mungkin tidak akan bermain sebaik aplikasi apa pun yang dijalankan pengguna pada saat yang sama).
Perhatikan bahwa kelas memori rupanya tidak perlu kelipatan 8MB.
Kita dapat melihat dari atas bahwa
getMemoryClass()
hasilnya tidak berubah untuk konfigurasi perangkat / OS yang diberikan, sedangkan nilai maxMemory () berubah ketika heap diatur secara berbeda oleh pengguna.Pengalaman praktis saya sendiri adalah bahwa pada G1 (yang memiliki kelas memori 16), jika saya secara manual memilih 24MB sebagai ukuran tumpukan, saya dapat berjalan tanpa kesalahan bahkan ketika penggunaan memori saya dibiarkan melayang hingga 20MB (mungkin itu bisa setinggi 24MB, meskipun saya belum mencoba ini). Tetapi aplikasi ish besar lainnya yang serupa mungkin saja memerah karena ingatan saya sendiri. Dan, sebaliknya, aplikasi saya bisa memerah dari memori jika aplikasi pemeliharaan tinggi lainnya dibawa ke latar depan oleh pengguna.
Jadi, Anda tidak dapat melebihi jumlah memori yang ditentukan oleh
maxMemory()
. Dan, Anda harus mencoba untuk tetap dalam batas yang ditentukan olehgetMemoryClass()
. Salah satu cara untuk melakukan itu, jika semuanya gagal, mungkin untuk membatasi fungsionalitas untuk perangkat tersebut dengan cara yang menghemat memori.Akhirnya, jika Anda berencana untuk membahas jumlah megabita yang ditentukan dalam
getMemoryClass()
, saran saya adalah bekerja keras dan lama dalam menyimpan dan memulihkan keadaan aplikasi Anda, sehingga pengalaman pengguna hampir tidak terganggu jika suatuonStop()
/onResume()
siklus terjadi.Dalam kasus saya, untuk alasan kinerja saya membatasi aplikasi saya ke perangkat yang menjalankan 2.2 dan di atasnya, dan itu berarti bahwa hampir semua perangkat yang menjalankan aplikasi saya akan memiliki memoryClass 24 atau lebih tinggi. Jadi saya dapat merancang untuk menempati tumpukan hingga 20MB dan merasa cukup percaya diri bahwa aplikasi saya akan bermain bagus dengan aplikasi lain yang mungkin dijalankan pengguna pada saat yang sama.
Tetapi akan selalu ada beberapa pengguna yang di-rooting yang memuat Android versi 2.2 atau di atas ke perangkat yang lebih lama (mis., G1). Ketika Anda menemukan konfigurasi seperti itu, idealnya, Anda harus mengurangi penggunaan memori Anda, bahkan jika
maxMemory()
memberi tahu Anda bahwa Anda bisa jauh lebih tinggi daripada 16MB yanggetMemoryClass()
memberi tahu Anda bahwa Anda harus menargetkan. Dan jika Anda tidak dapat memastikan bahwa aplikasi Anda akan hidup sesuai anggaran itu, maka setidaknya pastikan bahwaonStop()
/onResume()
berfungsi dengan mulus.getMemoryClass()
, seperti yang ditunjukkan oleh Diane Hackborn (hackbod) di atas, hanya tersedia kembali ke API level 5 (Android 2.0), dan karena itu, seperti yang ia sarankan, Anda dapat mengasumsikan bahwa perangkat keras fisik perangkat apa pun yang menjalankan versi OS sebelumnya dirancang. untuk secara optimal mendukung aplikasi yang menempati ruang tumpukan tidak lebih dari 16MB.Sebaliknya,
maxMemory()
menurut dokumentasi, tersedia sepanjang perjalanan kembali ke level API 1.maxMemory()
, pada pra-2.0 versi, mungkin akan mengembalikan nilai 16MB, tapi aku lakukan melihat bahwa dalam saya (lama kemudian) versi CyanogenMod pengguna dapat memilih nilai heap serendah 12MB, yang mungkin akan menghasilkan batas heap yang lebih rendah, dan jadi saya sarankan Anda terus mengujimaxMemory()
nilainya, bahkan untuk versi OS sebelum 2.0. Anda bahkan mungkin harus menolak untuk menjalankan jika nilai ini tidak ditetapkan lebih rendah dari 16MB, jika Anda harus memiliki lebih darimaxMemory()
indikasi yang diizinkan.sumber
API resmi adalah:
sumber
Debug.getNativeHeapSize()
akan melakukan trik, saya harus berpikir. Itu sudah ada sejak 1.0.The
Debug
kelas memiliki banyak metode yang bagus untuk melacak alokasi dan kekhawatiran kinerja lainnya. Juga, jika Anda perlu mendeteksi situasi dengan memori rendah, periksaActivity.onLowMemory()
.sumber
Begini cara melakukannya:
Mendapatkan ukuran tumpukan maksimum yang dapat digunakan aplikasi:
Mendapatkan jumlah tumpukan yang digunakan aplikasi Anda saat ini:
Mendapatkan seberapa banyak tumpukan yang kini dapat digunakan aplikasi Anda (memori yang tersedia):
Dan, untuk memformat masing-masing dengan baik, Anda dapat menggunakan:
sumber
Ini mengembalikan ukuran tumpukan maksimum dalam byte:
Saya menggunakan ActivityManager.getMemoryClass () tetapi pada CyanogenMod 7 (saya tidak mengujinya di tempat lain) mengembalikan nilai yang salah jika pengguna menetapkan ukuran tumpukan secara manual.
sumber
getMemoryClass
tampaknya menyiratkan bahwa jumlahnya mungkin tidak sama dengan ukuran heap yang tersedia untuk vm Anda, dan karena doc untukgetNativeHeapSize
... pendiam, saya benar-benar berpikirRuntime.getRuntime().maxMemory()
adalah jawaban terbaik.Beberapa operasi lebih cepat daripada pengelola ruang java heap. Menunda pengoperasian untuk beberapa waktu dapat membebaskan ruang memori. Anda dapat menggunakan metode ini untuk menghindari kesalahan ukuran tumpukan:
sumber
AvailableMemoryPercentage
sesuai dengan rumus: berapa banyak memori perangkat saat ini bebas.MIN_AVAILABLE_MEMORY_PERCENTAGE
adalah parameter khusus Anda, ambang di mana Anda mulai menunggu pengumpul sampah untuk melakukan tugasnya.Asus Nexus 7 (2013) 32Gig: getMemoryClass () = 192 maxMemory () = 201326592
Saya membuat kesalahan dengan membuat prototip permainan saya di Nexus 7, dan kemudian menemukan kehabisan memori segera di tablet 4.04 generik istri saya (memoryclass 48, maxmemory 50331648)
Saya perlu merestrukturisasi proyek saya untuk memuat lebih sedikit sumber daya ketika saya menentukan memoryclass rendah.
Apakah ada cara di Jawa untuk melihat ukuran tumpukan saat ini? (Saya bisa melihatnya dengan jelas di logCat ketika debugging, tapi saya ingin cara melihatnya dalam kode untuk beradaptasi, seperti jika currentheap> (maxmemory / 2) membongkar bitmap berkualitas tinggi memuat kualitas rendah
sumber
Apakah maksud Anda secara terprogram, atau hanya ketika Anda sedang mengembangkan dan debugging? Jika yang terakhir, Anda bisa melihat info itu dari perspektif DDMS di Eclipse. Ketika emulator Anda (mungkin bahkan telepon fisik yang dicolokkan) sedang berjalan, itu akan mencantumkan proses aktif di jendela di sebelah kiri. Anda dapat memilihnya dan ada opsi untuk melacak alokasi heap.
sumber
nilainya b
nilainya adalah MB
sumber
rt
? Di mana dinyatakan?