Apa yang perlu dimuat JVM adalah aliran biner, yang dapat dalam bentuk file .class atau formulir lainnya. Jika Anda mendesainnya sesuai dengan standar pemuatan, tidak akan ada masalah besar.
Berikut ini terutama menganalisis dua masalah mekanisme dan standar:
Pertama, mari kita ambil mekanisme pemuatan file kelas Java, yang mirip dengan mekanisme pemuatan variabel. Pertama -tama memuat file kelas ke dalam memori, kemudian memverifikasi, memars dan menginisialisasi data, dan akhirnya membentuk jenis Java yang dapat digunakan mesin virtual secara langsung. Karena Java mengadopsi mekanisme JIT, akan lambat untuk memuat, tetapi keunggulannya jelas, ia memiliki fleksibilitas tinggi dan mendukung pemuatan dinamis dan koneksi dinamis.
Selanjutnya, mari kita bicara tentang proses pemuatan kelas:
Proses dasar pemuatan kelas adalah dalam urutan berikut, tetapi beberapa tidak sepenuhnya dalam urutan ini, dan beberapa berada dalam urutan yang tidak teratur. Misalnya, pemuatan dinamis membutuhkan inisialisasi dan kemudian parsing.
1. Memuat
Terserah mesin virtual untuk memutuskan, tetapi ada juga kasus di mana fase di atas dieksekusi karena fase berikut akan dieksekusi.
Saat ini, mesin virtual melakukan tiga hal:
Pertama, baca aliran biner file melalui nama yang sepenuhnya memenuhi syarat;
Kedua, masukkan metode dan variabel statis ke dalam file ke dalam area metode;
Ketiga, hasilkan objek dan masukkan ke dalam tumpukan sebagai portal akses.
Perhatikan bahwa yang pertama adalah membaca aliran biner, dan tidak mengatakan file mana yang dibaca atau dari mana dibacanya. Oleh karena itu, ia menciptakan skalabilitas yang kuat di Java, yang dapat dari JAR, ZIP, atau dari lapisan jaringan, lapisan basis data, dll.
Terutama deklarasi objek dan area metode.
2. Verifikasi
Pastikan bahwa aliran biner memenuhi persyaratan mesin virtual dan tidak memenuhi VerifyError.
Pertama, verifikasi format file, apakah ada angka ajaib, dan apakah mereka memenuhi persyaratan file java;
Kedua, verifikasi metadata, apakah itu sesuai dengan spesifikasi kode Java, seperti apakah kelas abstrak secara langsung dipakai, apakah kelas biasa memiliki objek kelas induk tidak langsung atau langsung, dll.; Ketiga, verifikasi bytecode, menganalisis aliran data dan aliran kontrol, dan memastikan bahwa tidak akan ada perilaku yang membahayakan mesin virtual, seperti apakah akan memanggil instruksi yang tidak ada, apakah akan menetapkan kelas induk ke subkelas, apakah akan menetapkan objek ke objek jenis ini, dll.;
Keempat, verifikasi referensi simbolik, terutama apakah deskripsi kelas, variabel, dan metode dapat ditemukan, seperti apakah file tersebut dapat ditemukan dengan nama yang sepenuhnya memenuhi syarat, apakah dapat diakses, dll.
Terutama menentukan struktur internal
3. Persiapkan
Menetapkan nilai awal ke variabel kelas biasanya nilai 0 seperti variabel statis, tanpa menetapkan nilai ke variabel instance.
4. Analisis
Proses mengubah referensi simbolik dalam kumpulan konstan menjadi referensi langsung. Referensi simbolis yang disebutkan di sini mengacu pada jenis variabel, dan referensi langsung mengacu pada pegangan yang dapat langsung berlokasi ke objek. Kelas, metode, bidang, parsing antarmuka, dapatkan objek yang relevan sesuai dengan nama yang sepenuhnya memenuhi syarat, dan dapatkan jenisnya. Jika tidak ada akses ke kelas, ilegalAccessError akan dilemparkan, tidak ada lapangan nosuchfielderror yang akan dilemparkan, tidak ada metode nosuchmethoderror yang akan dilemparkan, jika itu adalah kelas atau tidak, antarmuka akan dilemparkan.
5. Inisialisasi
Memuat kelas dan sumber daya yang diperlukan sesuai dengan persyaratan program. Hanya ada empat situasi, dan Anda harus secara aktif menginisialisasi sebelum Anda dapat melakukan operasi berikutnya, jadi Anda harus terlebih dahulu melakukan empat langkah di atas.
Pertama, kelas dengan kata kunci baru atau statis, baru menghasilkan objek, dan beban statis statis, keduanya jelas akan diinisialisasi;
Kedua, jika Anda menggunakan kelas, tidak ada yang dapat Anda lakukan;
Ketiga, metode di kelas refleksi harus diinisialisasi, bukan?
Keempat, kelas eksekusi utama, kelas yang menggunakan metode utama. Situasi inisialisasi pasif lainnya tidak perlu dipertimbangkan.
Contoh kecil:
kelas publik superclass {static {system.out.println ("superclass !!");} public static int value = 1;} Subkelas kelas publik memperluas superclass {static {System.out.println ("Subclass !!");}} public class testclass {public static void static (string [] !! "); {System.out.println (subclass.Value); superclass superclass = subclass baru ();}} superclass !! 1SubClass !!Hasil eksekusi menunjukkan masalah: ketika subkelas memanggil variabel kelas induk, subkelas tidak diinisialisasi karena hubungan kode saat ini tidak ada hubungannya dengan subkelas; Ketika subkelas diinisialisasi, kelas induk tidak diinisialisasi lagi karena kelas induk telah diinisialisasi dalam badan metode saat ini. Satu -satunya perbedaan antara antarmuka dan kelas induk adalah bahwa inisialisasi antarmuka tidak memerlukan antarmuka induk, dan itu akan diinisialisasi hanya ketika antarmuka induk digunakan, dan konstruktor kelas yang sama akan dihasilkan.
Pada saat ini, konstruktor kelas akan dimuat dan semua variabel di kelas akan diinisialisasi. Tentu saja, kelas induk akan diinisialisasi sebelum kelas anak.
6. Penggunaan
Setelah memuat, cara menyebutnya, menggambar, perhitungan, dll.
7. Hapus instalasi
Kelas tidak lagi dipanggil
Apakah kedua kelas tersebut sama terutama tergantung pada pemuatan pertama menggunakan loader yang sama, dan alamat nama yang sepenuhnya memenuhi syarat kedua adalah sama
Mengapa mengajukan pertanyaan di atas? Selanjutnya, kita akan berbicara tentang mekanisme pemuatan mesin virtual.
Dari perspektif mesin virtual Java, ada dua loader kelas, satu disebut System Loader (Bootstrap ClassLoader), dan yang lainnya disebut custom loader (Extends ClassLoader). Ini dibagi menjadi dua, satu disebut loader aplikasi dan yang lainnya disebut loader kelas ekstensi, yang umumnya default ke yang pertama; dan pemuatan aplikasi kami terutama dilakukan oleh tiga loader di atas. Hubungan antara ketiganya adalah aplikasi> ekstensi> bootsrap. Mekanisme delegasi induk mengacu pada kombinasi dua pasangan. Loader anak pertama -tama memanggil metode orang tua loader, dan objek target tidak ditemukan sebelum menggunakan loader anak.
Kode pseudo adalah sebagai berikut:
LoadClass (nama string, boolean resolve) {class c = findloadedclass () if (c == null) {if (parent! = null) c = parent.LoadClass (name, false); c = findbootstrapclassnull (name);} catch (classnotfoundexception e) {if if (c == dompet); dompa (dompet) (dompet) {if (name);Java menganjurkan bahwa kami menulis logika kelas panggilan kami di FindClass, yang akan membantu kami menggunakan mekanisme delegasi induk secara normal.
Hancurkan 1. Tulis ulang LoadClass
Hancurkan 2. Gunakan loader konteks utas untuk membiarkan orangtua loader memanggil metode pemuat anak
Penghancuran 3. Metode yang umum digunakan untuk pemuatan panas adalah untuk menyesuaikan loader kelas dan menimpa modul bug asli - OSGI
Namun, jika aturan antara loader khusus bingung dan ada masalah merujuk satu sama lain pada saat yang sama, kelas pada akhirnya tidak akan ditemukan, dan kebuntuan benang dan kebocoran memori akan terjadi.
Mengenai perbaikan panas, juga dikenal sebagai plug-in, yang paling populer adalah perbaikan panas, Nuwa, Droidfix, dan Fix, dll. Kerangka kerja ini dapat ditemukan di GitHub atau di tempat lain. Prinsip -prinsipnya seperti di atas, metodenya beragam, ada cakupan, pengalihan, dll., Melalui konfigurasi, tindakan pengaturan, dll.; Sebagai plug-in, kondisi berikut perlu dipenuhi:
1. Dapat dipasang secara mandiri, tetapi tidak dapat dijalankan secara mandiri
2. Kompatibilitas mundur, dapat diperluas
3. Ini hanya dapat berjalan dalam program host, dan dapat dinonaktifkan atau diganti
Contoh penjelasan di atas dari Java Advanced Virtual Machine Mekanisme Pemuatan adalah semua konten yang saya bagikan dengan Anda. Saya harap Anda dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.