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:
Runtime rt = Runtime.getRuntime();
long maxMemory = rt.maxMemory();
Log.v("onCreate", "maxMemory:" + Long.toString(maxMemory));
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:
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
int memoryClass = am.getMemoryClass();
Log.v("onCreate", "memoryClass:" + Integer.toString(memoryClass));
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 dalam getMemoryClass()
(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()
dan getMemoryClass()
untuk empat perangkat berbeda yang menjalankan CyanogenMod, menggunakan dua nilai tumpukan (yang diatur secara manual) untuk masing-masing:
- G1:
- Dengan VM Heap Size diatur ke 16MB:
- maxMemory: 16777216
- getMemoryClass: 16
- Dengan VM Heap Size diatur ke 24MB:
- maxMemory: 25165824
- getMemoryClass: 16
- Moto Droid:
- Dengan VM Heap Size diatur ke 24MB:
- maxMemory: 25165824
- getMemoryClass: 24
- Dengan VM Heap Size diatur ke 16MB:
- maxMemory: 16777216
- getMemoryClass: 24
- Nexus One:
- Dengan VM Heap size diatur ke 32MB:
- maxMemory: 33554432
- getMemoryClass: 32
- Dengan VM Heap size diatur ke 24MB:
- maxMemory: 25165824
- getMemoryClass: 32
- GT Viewsonic:
- Dengan VM Heap Size diatur ke 32:
- maxMemory: 33554432
- getMemoryClass: 32
- Dengan VM Heap Size diatur ke 64:
- maxMemory: 67108864
- getMemoryClass: 32
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:
- 7 November
- maxMemory: 62914560
- getMemoryClass: 60
Juga (per Kishore dalam komentar di bawah):
- HTC One X
- maxMemory: 67108864
- getMemoryClass: 64
Dan (per komentar aliasuppi):
- Samsung Galaxy Core Plus
- maxMemory: (Tidak ditentukan dalam komentar)
- getMemoryClass: 48
- largeMemoryClass: 128
Per komentar dari cmcromance:
- Galaxy S3 (Jelly Bean) tumpukan besar
- maxMemory: 268435456
- getMemoryClass: 64
Dan (per komentar Tencent):
- LG Nexus 5 (4.4.3) normal
- maxMemory: 201326592
- getMemoryClass: 192
- LG Nexus 5 (4.4.3) tumpukan besar
- maxMemory: 536870912
- getMemoryClass: 192
- Galaxy Nexus (4.3) normal
- maxMemory: 100663296
- getMemoryClass: 96
- Galaxy Nexus (4.3) banyak
- maxMemory: 268435456
- getMemoryClass: 96
- Galaxy S4 Play Store Edition (4.4.2) normal
- maxMemory: 201326592
- getMemoryClass: 192
- Galaxy S4 Play Store Edition (4.4.2) tumpukan besar
- maxMemory: 536870912
- getMemoryClass: 192
Perangkat lain
- Huawei Nexus 6P (6.0.1) normal
- maxMemory: 201326592
- getMemoryClass: 192
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 meninggalkan getMemoryClass()
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 oleh getMemoryClass()
. 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 suatu onStop()
/ 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 yang getMemoryClass()
memberi tahu Anda bahwa Anda harus menargetkan. Dan jika Anda tidak dapat memastikan bahwa aplikasi Anda akan hidup sesuai anggaran itu, maka setidaknya pastikan bahwa onStop()
/ 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 menguji maxMemory()
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 dari maxMemory()
indikasi yang diizinkan.