Android luar dalam: perbandingan Dalvik dan ART

Halo, Habr! Sekitar setengah tahun yang lalu saya menerbitkan "panduan" JVM yang rinci . Posting tersebut, secara umum, pergi, dan di komentar mereka bertanya apakah "ada sesuatu yang direncanakan untuk android". Akhirnya, saya mendapatkannya.







Dalam posting ini, kita akan berbicara tentang runtime Android. Secara khusus, saya akan mencoba menjelaskan secara singkat namun ringkas bagaimana ART dan Dalvik berbeda, dan bagaimana alat pengembangan Android telah meningkat dari waktu ke waktu. Topik ini jelas bukan hal baru, tapi saya harap ini akan berguna bagi mereka yang baru mulai mempelajarinya. Siapa yang peduli - selamat datang di kucing.



Mesin virtual



Pertama, mari kita lihat bagaimana JVM berbeda dari DVM.



Java Virtual Machine adalah mesin virtual yang mampu menjalankan bytecode Java terlepas dari platform yang mendasarinya. Ini didasarkan pada prinsip "Tulis sekali, jalankan di mana saja". Bytecode Java dapat dijalankan di mesin apa pun yang mampu mendukung JVM.



Kompilator Java mengonversi file .java menjadi file kelas (bytecode). Bytecode diteruskan ke JVM, yang mengkompilasinya ke kode mesin untuk dieksekusi secara langsung di CPU.



Fitur JVM:



  • Ini memiliki arsitektur tumpukan: tumpukan digunakan sebagai struktur data di mana metode ditempatkan dan disimpan. Ia bekerja dalam skema LIFO atau "Last in - First Out" atau "Last in, first out".
  • Hanya dapat menjalankan file kelas.
  • Menggunakan kompiler JIT.


Dalvik Virtual Machine (DVM) adalah mesin virtual Java yang dikembangkan dan ditulis oleh Dan Bornstein dan lainnya sebagai bagian dari platform seluler Android.



Kami dapat mengatakan bahwa Dalvik adalah lingkungan untuk menjalankan komponen sistem operasi Android dan aplikasi khusus. Setiap proses berjalan di ruang alamat terisolasi sendiri. Saat pengguna meluncurkan aplikasi (atau sistem operasi meluncurkan salah satu komponennya), inti mesin virtual Dalvik (Zygote Dalvik VM) membuat proses terpisah yang terlindungi dalam memori bersama, di mana VM langsung diterapkan sebagai lingkungan untuk meluncurkan aplikasi. Dengan kata lain, dari dalam, Android terlihat seperti sekumpulan mesin virtual Dalvik, yang masing-masing menjalankan aplikasi.



Fitur DVM:



  • Menggunakan arsitektur berbasis register: struktur data tempat metode ditempatkan didasarkan pada register prosesor. Karena tidak adanya operasi POP dan PUSH, instruksi di mesin virtual terdaftar dijalankan lebih cepat daripada instruksi serupa di mesin virtual bertumpuk.
  • Menjalankan bytecode format asli: Android dexer (kita akan membicarakannya di bawah) mengonversi file kelas ke format .dex, dioptimalkan untuk eksekusi pada VM Dalvik. Tidak seperti file kelas, file dex berisi beberapa kelas sekaligus.








Anda dapat membaca lebih lanjut tentang arsitektur DVM di sini .



Android Dexer



Pengembang Android tahu bahwa proses mengonversi bytecode Java menjadi .dex bytecode untuk Android Runtime adalah langkah kunci dalam membuat APK. Kompiler dex sebagian besar bekerja secara tersembunyi dalam pengembangan aplikasi sehari-hari, tetapi secara langsung memengaruhi waktu pembuatan aplikasi, ukuran file .dex, dan kinerja waktu proses.



Seperti yang telah disebutkan, file dex itu sendiri berisi beberapa kelas sekaligus. Garis duplikat dan konstanta lain yang digunakan di beberapa file kelas disertakan hanya untuk menghemat ruang. Bytecode Java juga diubah menjadi set instruksi alternatif yang digunakan oleh DVM. File dex yang tidak terkompresi biasanya beberapa persen lebih kecil dari arsip Java terkompresi (JAR) yang diperoleh dari file .class yang sama.



Awalnya, file kelas diubah menjadi file dex menggunakan kompiler DX bawaan. Namun mulai Android Studio 3.1 dan seterusnya, D8 menjadi compiler default . Dibandingkan dengan kompiler DX, D8 mengompilasi lebih cepat dan mengeluarkan file dex yang lebih kecil, sekaligus memberikan kinerja aplikasi yang lebih baik pada waktu proses. Bytecode dex yang diperoleh dengan cara ini diminimalkan menggunakan utilitas ProGuard sumber terbuka . Hasilnya, kami mendapatkan file dex yang sama, tetapi lebih kecil. File dex ini kemudian digunakan untuk membangun apk dan akhirnya diterapkan ke perangkat Android.







Namun di belakang D8 pada 2018 datanglah R8, yang sebenarnya adalah D8 yang sama, hanya dengan tambahan.



Saat bekerja dengan Android Studio 3.4 dan plugin Android Gradle 3.4.0 atau yang lebih tinggi, Proguard tidak lagi digunakan untuk mengoptimalkan kode pada waktu kompilasi. Sebaliknya, plugin bekerja secara default dengan R8, yang melakukan penyusutan Kode, Pengoptimalan, dan Obfuscation itu sendiri. Meskipun R8 hanya menawarkan sebagian dari fitur yang disediakan oleh Proguard, R8 memungkinkan Anda untuk melakukan konversi bytecode Java ke bytecode dex satu kali, yang selanjutnya mengurangi waktu build.







R8 dan pengurangan kode





Biasanya, aplikasi menggunakan pustaka pihak ketiga seperti Jetpack, Gson, Layanan Google Play. Saat kita menggunakan salah satu dari perpustakaan ini, seringkali aplikasi hanya menggunakan sebagian kecil dari setiap perpustakaan individu. Tanpa penyusutan kode, semua kode perpustakaan disimpan dalam aplikasi Anda.



Itu terjadi bahwa pengembang menggunakan kode verbose untuk meningkatkan keterbacaan dan pemeliharaan aplikasi. Misalnya, nama variabel yang bermakna dan pola desain dapat digunakan untuk membantu orang lain memahami kode dengan lebih mudah. Tetapi template cenderung mengarah ke lebih banyak kode daripada yang diperlukan.



Di sinilah R8 datang untuk menyelamatkan. Ini memungkinkan Anda untuk secara signifikan mengurangi ukuran aplikasi, mengoptimalkan ukuran bahkan kode yang sebenarnya digunakan oleh aplikasi tersebut.



Sebagai contoh, di bawah ini adalah angka-angka dari laporan Shrinking Your App with R8 , yang dipresentasikan di Android Dev Summit '19:







Dan seperti inilah perbandingan efisiensi R8 pada tahap rilis beta (diambil dari sumber Android Developers Blog ):













Lebih detail dapat ditemukan dalam dokumentasi dan laporan kantor .



ART vs DVM di Android



DVM dirancang khusus untuk perangkat seluler dan digunakan sebagai

mesin virtual untuk menjalankan aplikasi android hingga Android 4.4 Kitkat.



Dimulai dengan versi ini, ART diperkenalkan sebagai runtime, dan di Android 5.0 (Lollipop) ART sepenuhnya menggantikan Dalvik.



Perbedaan utama yang jelas antara ART dan DVM adalah ART menggunakan kompilasi AOT, dan DVM menggunakan kompilasi JIT. Belum lama berselang, ART mulai menggunakan hibrida AOT dan JIT. Mari kita lihat lebih dekat.



DVM



  • Menggunakan kompilasi JIT: setiap kali aplikasi dimulai,
  • bagian dari kode yang diperlukan untuk menjalankan aplikasi dikompilasi. Sisa kode dikompilasi secara dinamis. Ini memperlambat peluncuran dan pengoperasian aplikasi, tetapi mengurangi waktu penginstalan.
  • , .
  • , DVM, , , ART.
  • , CPU.
  • Dalvik “” 4.4.






ART



  • AOT , . , .
  • , .
  • AOT , DVM.
  • , - .
  • Pengumpulan Sampah atau Pengumpulan Sampah yang Lebih Baik. Saat menggunakan Dalvik, pengumpul sampah harus melakukan 2 heap pass, yang menyebabkan UX buruk. Dalam kasus ART, tidak ada situasi seperti itu: ia membersihkan tumpukan sekali untuk mengkonsolidasikan memori.






Dan diagram kecil Dalvik vs ART:





JIT + AOT dalam ART



Android Runtime (ART) sejak Android 7 menyertakan compiler JIT dengan pembuatan profil kode. Kompilator JIT melengkapi kompilator AOT dan meningkatkan kinerja runtime, menghemat ruang disk, dan mempercepat pembaruan aplikasi dan sistem.



Ini terjadi dengan cara berikut:





Alih-alih menjalankan kompilasi AOT setiap aplikasi selama fase instalasi, ia menjalankan aplikasi di bawah kendali mesin virtual menggunakan kompiler JIT (hampir sama seperti di Android <5.0), tetapi tetap melacaknya bagian dari kode aplikasi paling sering dieksekusi. Informasi ini kemudian digunakan untuk AOT menyusun bagian kode ini. Operasi terakhir dilakukan hanya ketika smartphone tidak aktif saat sedang mengisi daya.



Secara sederhana, sekarang dua pendekatan yang sangat berbeda bekerja sama, yang memberikan keuntungannya:



  • kompilasi yang lebih efisien - ketika aplikasi diluncurkan dalam waktu nyata, kompilator memiliki kesempatan untuk mempelajari lebih banyak tentang pekerjaannya daripada dengan melakukan analisis statis, dan sebagai hasilnya, metode pengoptimalan yang lebih tepat diterapkan untuk setiap situasi;
  • pemeliharaan RAM dan memori permanen - kode byte lebih ringkas daripada kode mesin, dan jika Anda melakukan kompilasi AOT hanya pada bagian tertentu dari aplikasi dan tidak mengkompilasi aplikasi yang tidak digunakan pengguna, Anda dapat menghemat ruang memori NAND secara signifikan;
  • peningkatan dramatis dalam pemasangan dan kecepatan boot pertama setelah pembaruan sistem - tanpa kompilasi AOT, tanpa penundaan.


Baca lebih lanjut tentang implementasi compiler JIT di ART di sini .



Kesimpulan



Dalam artikel ini, saya mencoba melihat perbedaan utama antara Dalvik dan ART, dan secara umum melihat bagaimana Android telah meningkatkan alat pengembangannya dari waktu ke waktu.



ART masih dalam pengembangan dengan fitur-fitur baru yang ditambahkan untuk meningkatkan pengalaman bagi pengguna dan pengembang.



Jika itu membantu, beri tahu saya di komentar.



All Articles