Peningkatan Android 8.0 ART

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

Pemadatan sampah secara bersamaan

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

  • GC selalu memadatkan heap: rata-rata ukuran heap 32% lebih kecil dibandingkan Android 7.0.
  • Pemadatan memungkinkan alokasi objek penunjuk benjolan lokal thread: Alokasi 70% lebih cepat dibandingkan di Android 7.0.
  • Menawarkan waktu jeda 85% lebih kecil untuk benchmark H2 dibandingkan dengan Android 7.0 GC.
  • Waktu jeda tidak lagi berskala dengan ukuran heap; aplikasi harus dapat menggunakan tumpukan besar tanpa khawatir akan jank.
  • Detail implementasi GC - Baca hambatannya:
    • Hambatan baca adalah sejumlah kecil pekerjaan yang dilakukan untuk setiap bidang objek yang dibaca.
    • Ini dioptimalkan dalam kompiler, namun mungkin memperlambat beberapa kasus penggunaan.

Pengoptimalan lingkaran

Berbagai macam optimasi loop digunakan oleh ART dalam rilis Android 8.0:

  • Batas memeriksa eliminasi
    • Statis: rentang terbukti berada dalam batas pada waktu kompilasi
    • Dinamis: pengujian run-time memastikan loop tetap berada dalam batas (deopt sebaliknya)
  • Eliminasi variabel induksi
    • Hapus induksi mati
    • Gantikan induksi yang digunakan hanya setelah perulangan dengan ekspresi bentuk tertutup
  • Penghapusan kode mati di dalam badan loop, penghapusan seluruh loop yang mati
  • Pengurangan kekuatan
  • Transformasi loop: pembalikan, pertukaran, pemisahan, pembukaan gulungan, unimodular, dll.
  • SIMDisasi (juga disebut vektorisasi)

Pengoptimal loop berada dalam jalur pengoptimalannya sendiri di kompiler ART. Kebanyakan optimasi loop mirip dengan optimasi dan penyederhanaan di tempat lain. Tantangan muncul dengan beberapa optimasi yang menulis ulang CFG dengan cara yang lebih rumit dari biasanya, karena sebagian besar utilitas CFG (lihat node.h) fokus pada pembuatan CFG, bukan penulisan ulang.

Analisis hierarki kelas

ART di Android 8.0 menggunakan Class Hierarchy Analysis (CHA), sebuah optimasi compiler yang mendevirtualisasikan panggilan virtual menjadi panggilan langsung berdasarkan informasi yang dihasilkan dengan menganalisis hierarki kelas. Panggilan virtual mahal karena diimplementasikan berdasarkan pencarian vtable, dan memerlukan beberapa beban dependen. Panggilan virtual juga tidak dapat dimasukkan.

Berikut ringkasan penyempurnaan terkait:

  • Pembaruan status metode implementasi tunggal dinamis - Di akhir waktu penautan kelas, ketika vtable telah diisi, ART melakukan perbandingan entri demi entri ke vtable kelas super.
  • Optimasi kompiler - Kompiler akan memanfaatkan info implementasi tunggal suatu metode. Jika metode A.foo memiliki flag implementasi tunggal yang disetel, kompiler akan mendevirtualisasikan panggilan virtual menjadi panggilan langsung, dan selanjutnya mencoba memasukkan panggilan langsung sebagai hasilnya.
  • Pembatalan kode yang dikompilasi - Juga di akhir waktu penautan kelas ketika info implementasi tunggal diperbarui, jika metode A.foo yang sebelumnya memiliki implementasi tunggal tetapi status tersebut sekarang tidak valid, semua kode yang dikompilasi bergantung pada asumsi metode A. foo memiliki kebutuhan implementasi tunggal agar kode yang dikompilasinya tidak valid.
  • Deoptimisasi - Untuk kode kompilasi langsung yang ada di tumpukan, deoptimisasi akan dimulai untuk memaksa kode kompilasi yang tidak valid ke mode juru bahasa untuk menjamin kebenarannya. Mekanisme deoptimisasi baru yang merupakan gabungan deoptimisasi sinkron dan asinkron akan digunakan.

Cache sebaris dalam file .oat

ART sekarang menggunakan cache inline dan mengoptimalkan situs panggilan yang datanya cukup. Fitur cache inline mencatat informasi runtime tambahan ke dalam profil dan menggunakannya untuk menambahkan optimasi dinamis ke kompilasi sebelumnya.

tata letak Dex

Dexlayout adalah pustaka yang diperkenalkan di Android 8.0 untuk menganalisis file dex dan menyusun ulang berdasarkan profil. Dexlayout bertujuan untuk menggunakan informasi pembuatan profil runtime untuk menyusun ulang bagian file dex selama kompilasi pemeliharaan idle pada perangkat. Dengan mengelompokkan bagian-bagian file dex yang sering diakses bersama-sama, program dapat memiliki pola akses memori yang lebih baik dari peningkatan lokalitas, menghemat RAM dan mempersingkat waktu start up.

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

Penghapusan cache Dex

Hingga Android 7.0, objek DexCache memiliki empat array besar, sebanding dengan jumlah elemen tertentu di DexFile, yaitu:

  • string (satu referensi per DexFile::StringId),
  • jenis (satu referensi per DexFile::TypeId),
  • metode (satu penunjuk asli per DexFile::MethodId),
  • bidang (satu penunjuk asli 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.

Kinerja juru bahasa

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

  1. Panggil kinerja.
  2. Manipulasi string, dan metode pengguna berat lainnya yang diakui sebagai intrinsik di Dalvik.
  3. Penggunaan memori tumpukan lebih tinggi.

Android 8.0 mengatasi masalah ini.

Lebih sebaris

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

  1. Inlining dari file dex lain memerlukan penggunaan cache dex dari file dex lainnya, tidak seperti inlining 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 kelas.
  2. Peta tumpukan hanya menyandikan indeks metode dalam file dex saat ini.

Untuk mengatasi keterbatasan ini, Android 8.0:

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

Peningkatan sinkronisasi

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

Metode asli yang lebih cepat

Panggilan asli yang lebih cepat ke Java Native Interface (JNI) tersedia menggunakan anotasi @FastNative dan @CriticalNative . Pengoptimalan runtime ART bawaan ini mempercepat transisi JNI dan menggantikan notasi !bang JNI yang sekarang sudah tidak digunakan lagi. Anotasi tidak berpengaruh pada metode non-asli dan hanya tersedia untuk kode Bahasa Java platform di bootclasspath (tidak ada pembaruan Play Store).

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

Anotasi @CriticalNative menyediakan cara yang lebih cepat untuk menjalankan metode asli, dengan batasan berikut:

  • Metode harus statis—tidak ada objek untuk parameter, nilai kembalian, atau this yang tersirat.
  • Hanya tipe primitif yang diteruskan ke metode asli.
  • Metode asli tidak menggunakan parameter JNIEnv dan jclass dalam definisi fungsinya.
  • Metode ini harus terdaftar di RegisterNatives , bukan mengandalkan tautan JNI dinamis.

@FastNative dapat meningkatkan performa metode asli 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