Peningkatan ART Android 8.0

Runtime Android (ART) telah ditingkatkan secara signifikan dalam rilis Android 8.0. Daftar di bawah merangkum peningkatan yang dapat diharapkan produsen perangkat di ART.

Pengumpul sampah memori pemadatan serentak

Seperti yang diumumkan di Google I/O, ART menampilkan pengumpul sampah (GC) pemadatan serentak baru di Android 8.0. Pengumpul ini memadatkan heap setiap kali GC berjalan dan saat aplikasi berjalan, dengan hanya satu jeda singkat untuk memproses root thread. Berikut manfaatnya:

  • GC selalu memadatkan heap: ukuran heap rata-rata 32% lebih kecil dibandingkan dengan Android 7.0.
  • Pemadatan memungkinkan alokasi objek penunjuk bump lokal thread: Alokasi 70% lebih cepat daripada di Android 7.0.
  • Menawarkan waktu jeda 85% lebih kecil untuk tolok ukur H2 dibandingkan dengan GC Android 7.0.
  • Waktu jeda tidak lagi diskalakan dengan ukuran heap; aplikasi harus dapat menggunakan heap besar tanpa mengkhawatirkan jank.
  • Detail penerapan GC - Hambatan baca:
    • Penghalang baca adalah sejumlah kecil pekerjaan yang dilakukan untuk setiap pembacaan kolom objek.
    • Hal ini dioptimalkan di kompiler, tetapi dapat memperlambat beberapa kasus penggunaan.

Pengoptimalan loop

Berbagai pengoptimalan loop digunakan oleh ART dalam rilis Android 8.0:

  • Penghapusan pemeriksaan batas
    • Statis: rentang terbukti berada dalam batas pada waktu kompilasi
    • Dinamis: pengujian run-time memastikan loop tetap dalam batas (jika tidak, akan terjadi deoptimasi)
  • Penghapusan variabel induksi
    • Menghilangkan induksi mati
    • Ganti induksi yang digunakan hanya setelah loop dengan ekspresi bentuk tertutup
  • Penghapusan kode tidak terpakai di dalam isi loop, penghapusan seluruh loop yang menjadi tidak terpakai
  • Pengurangan kekuatan
  • Transformasi loop: pembalikan, pertukaran, pemisahan, pembukaan, unimodular, dll.
  • SIMDisasi (juga disebut vektorisasi)

Pengoptimal loop berada di proses pengoptimalan sendiri di compiler ART. Sebagian besar pengoptimalan loop serupa dengan pengoptimalan dan penyederhanaan di tempat lain. Tantangan muncul dengan beberapa pengoptimalan yang menulis ulang CFG dengan cara yang lebih rumit dari biasanya, karena sebagian besar utilitas CFG (lihat nodes.h) berfokus pada pembuatan CFG, bukan penulisan ulang.

Analisis hierarki class

ART di Android 8.0 menggunakan Analisis Hierarki Class (CHA), pengoptimalan compiler yang melakukan devirtualisasi panggilan virtual menjadi panggilan langsung berdasarkan informasi yang dihasilkan dengan menganalisis hierarki class. Panggilan virtual mahal karena diimplementasikan di sekitar pencarian vtable, dan memerlukan beberapa pemuatan dependen. Selain itu, panggilan virtual tidak dapat ditampilkan sebaris.

Berikut ringkasan peningkatan terkait:

  • Pembaruan status metode penerapan tunggal dinamis - Di akhir waktu penautan kelas, saat vtable telah diisi, ART melakukan perbandingan entri demi entri ke vtable superclass.
  • Pengoptimalan compiler - Compiler akan memanfaatkan info implementasi tunggal suatu metode. Jika metode A.foo memiliki setelan tanda implementasi tunggal, compiler akan mendevirtualisasi panggilan virtual menjadi panggilan langsung, dan selanjutnya mencoba menyisipkan panggilan langsung sebagai hasilnya.
  • Pembatalan validasi kode yang dikompilasi - Juga di akhir waktu penautan class saat info implementasi tunggal diperbarui, jika metode A.foo yang sebelumnya memiliki implementasi tunggal, tetapi status tersebut kini dibatalkan validasinya, semua kode yang dikompilasi yang bergantung pada asumsi bahwa metode A.foo memiliki implementasi tunggal harus dibatalkan validasi kode yang dikompilasinya.
  • Deoptimasi - Untuk kode yang dikompilasi langsung yang ada di stack, deoptimasi akan dimulai untuk memaksa kode yang dikompilasi yang tidak valid ke mode interpreter untuk menjamin kebenaran. Mekanisme deoptimasi baru yang merupakan gabungan dari deoptimasi sinkron dan asinkron akan digunakan.

Cache inline dalam file .oat

ART kini menggunakan cache inline dan mengoptimalkan situs panggilan yang memiliki cukup data. Fitur cache inline mencatat informasi runtime tambahan ke dalam profil dan menggunakannya untuk menambahkan pengoptimalan dinamis ke kompilasi di awal.

Dexlayout

Dexlayout adalah library yang diperkenalkan di Android 8.0 untuk menganalisis file dex dan mengurutkannya kembali sesuai dengan profil. Dexlayout bertujuan menggunakan informasi pemrofilan runtime untuk menyusun ulang bagian file dex selama kompilasi pemeliharaan saat perangkat dalam kondisi tidak ada aktivitas. Dengan mengelompokkan bagian file dex yang sering diakses bersama, program dapat memiliki pola akses memori yang lebih baik dari lokalitas yang ditingkatkan, sehingga menghemat RAM dan mempersingkat waktu mulai.

Karena informasi profil saat ini hanya tersedia setelah aplikasi dijalankan, dexlayout diintegrasikan dalam kompilasi di perangkat dex2oat selama pemeliharaan saat perangkat tidak digunakan.

Penghapusan cache Dex

Hingga Android 7.0, objek DexCache memiliki empat array besar, yang proporsional dengan jumlah elemen tertentu dalam DexFile, yaitu:

  • string (satu referensi per DexFile::StringId),
  • (satu referensi per DexFile::TypeId),
  • metode (satu pointer native per DexFile::MethodId),
  • kolom (satu pointer native per DexFile::FieldId).

Array ini digunakan untuk pengambilan cepat objek yang sebelumnya kita selesaikan. Di Android 8.0, semua array telah dihapus kecuali array metode.

Performa penerjemah

Performa interpreter meningkat secara signifikan dalam rilis Android 7.0 dengan diperkenalkannya "mterp" - interpreter yang menampilkan mekanisme pengambilan/dekode/interpretasi inti yang ditulis dalam bahasa assembly. Mterp dimodelkan setelah interpreter Dalvik yang cepat, dan mendukung arm, arm64, x86, x86_64, mips, dan mips64. Untuk kode komputasi, mterp Art kira-kira sebanding dengan interpreter cepat Dalvik. Namun, dalam beberapa situasi, kecepatannya bisa jauh lebih lambat - bahkan sangat lambat:

  1. Memanggil performa.
  2. Manipulasi string, dan penggunaan berat metode lain yang dikenali sebagai intrinsik di Dalvik.
  3. Penggunaan memori stack yang lebih tinggi.

Android 8.0 mengatasi masalah ini.

Lebih banyak penyisipan

Sejak Android 6.0, ART dapat menyisipkan panggilan apa pun dalam file dex yang sama, tetapi hanya dapat menyisipkan metode leaf dari file dex yang berbeda. Ada dua alasan untuk batasan ini:

  1. Penyisipan dari file dex lain memerlukan penggunaan cache dex dari file dex lain tersebut, tidak seperti penyisipan file dex yang sama, yang hanya dapat menggunakan kembali cache dex pemanggil. Cache dex diperlukan dalam kode yang dikompilasi untuk beberapa instruksi seperti panggilan statis, pemuatan string, atau pemuatan class.
  2. Peta stack hanya mengenkode indeks metode dalam file dex saat ini.

Untuk mengatasi batasan ini, Android 8.0:

  1. Menghapus akses cache dex dari kode yang dikompilasi (lihat juga bagian "Penghapusan cache dex")
  2. Memperluas encoding peta stack.

Peningkatan sinkronisasi

Tim ART menyetel jalur kode MonitorEnter/MonitorExit, dan mengurangi ketergantungan kami pada penghalang memori tradisional di ARMv8, menggantinya dengan instruksi yang lebih baru (acquire/release) jika memungkinkan.

Metode native yang lebih cepat

Panggilan native yang lebih cepat ke Java Native Interface (JNI) tersedia menggunakan anotasi @FastNative dan @CriticalNative. Pengoptimalan waktu proses ART bawaan ini mempercepat transisi JNI dan menggantikan notasi !bang JNI yang kini tidak digunakan lagi. Anotasi tidak berpengaruh pada metode non-native dan hanya tersedia untuk kode Bahasa Java platform di bootclasspath (tanpa update Play Store).

Anotasi @FastNative mendukung metode non-statis. Gunakan ini jika metode mengakses jobject sebagai parameter atau nilai yang ditampilkan.

Anotasi @CriticalNative memberikan cara yang lebih cepat untuk menjalankan metode native, dengan batasan berikut:

  • Metode harus statis—tidak ada objek untuk parameter, nilai yang ditampilkan, atau this implisit.
  • Hanya jenis primitif yang diteruskan ke metode native.
  • Metode bawaan tidak menggunakan parameter JNIEnv dan jclass dalam definisi fungsinya.
  • Metode harus didaftarkan dengan RegisterNatives, bukan mengandalkan penautan JNI dinamis.

@FastNative dapat meningkatkan performa metode native hingga 3x, dan @CriticalNative hingga 5x. Misalnya, transisi JNI yang diukur pada perangkat Nexus 6P:

Pemanggilan Java Native Interface (JNI) Waktu eksekusi (dalam nanodetik)
JNI Reguler 115
!bang JNI 60
@FastNative 35
@CriticalNative 25