Artikel ini membawakan anda pengetahuan yang berkaitan tentang java, yang terutamanya menganjurkan isu berkaitan JVM, termasuk pembahagian kawasan memori JVM, mekanisme pemuatan kelas JVM, kutipan sampah VM, dll. Mari lihat kandungan di bawah ini saya harap ia dapat membantu semua.
Kajian yang disyorkan: "tutorial video java"
Mengapa JVM perlu Bagaimana untuk membahagikan kawasan ini? Memori JVM digunakan daripada sistem pengendalian, dan JVM membahagikannya kepada modul kecil mengikut keperluan fungsian Dengan cara ini, tapak besar boleh dibahagikan kepada modul kecil, dan kemudian setiap modul itu bertanggungjawab ke atas fungsinya sendiri, jadi mari kita lihat fungsi kawasan ini
Kaunter program adalah yang terkecil dalam Kawasan memori, di mana terutamanya menyimpan alamat arahan seterusnya yang akan dilaksanakan (arahan itu ialah kod bait. Untuk menjalankan atur cara umum, JVM perlu memuatkan kod bait ke dalam memori, dan kemudian Atur cara itu kemudian mengeluarkan arahan satu oleh satu daripada memori dan meletakkannya pada CPU untuk pelaksanaan, jadi ia mesti ingat arahan mana yang sedang dilaksanakan dan di mana arahan seterusnya, kerana CPU bukan sahaja menyediakan perkhidmatan kepada satu proses, tetapi kepada semua Semua proses menyediakan perkhidmatan dan laksanakan program secara serentak. Dan kerana sistem pengendalian menjadualkan pelaksanaan dalam unit utas, setiap utas mesti mempunyai lokasi pelaksanaannya sendiri, iaitu setiap utas perlu mempunyai program untuk merekodkan kedudukan!)
Timbunan terutamanya menyimpan pembolehubah tempatan dan maklumat panggilan kaedah, selagi ia melibatkan panggilan kaedah baharu, ia akan Terdapat operasi "tekan" Setiap kali a kaedah dilaksanakan, akan ada operasi "tolak", dan setiap utas mempunyai salinan tindanan
Oleh itu, untuk rekursi, ia mesti Anda mesti mengawal keadaan rekursif, jika tidak, pengecualian limpahan tindanan (StackOverflowException) berkemungkinan berlaku!
Timbunan ialah kawasan terbesar ruang dalam ingatan, dan timbunan adalah kawasan terbesar dalam setiap proses Di sana. hanya satu salinan Berbilang benang dalam proses berkongsi timbunan, yang terutamanya menyimpan objek baru dan pembolehubah ahli objek. Contohnya, String s = new String() jika s di sini adalah dalam kaedah pada timbunan. Jika s ialah pembolehubah ahli, ia berada pada heap New String() ialah ontologi objek, dan objek itu adalah di mana ianya mudah dikelirukan juga Perkara penting ialah mengenai pengumpulan sampah, yang akan diperkenalkan secara terperinci kemudian 4 Kawasan kaedah
, The. Kod .java yang biasanya anda tulis akan menjadi .class (binary bytecode) selepas diterjemahkan oleh pengkompil Kemudian .class akan dimuatkan ke dalam memori dan dibina ke dalam objek kelas oleh JVM (proses pemuatan dipanggil "pemuatan kelas"), dan objek kelas ini akan disimpan dalam kawasan kaedah, yang secara khusus menerangkan rupa kelas (nama kelas, ahli kelas dan nama ahli mereka, jenis ahli, kaedah kelas dan nama Kaedah mereka, jenis kaedah, dan beberapa arahan... Di samping itu, perkara yang sangat penting disimpan dalam objek kelas, iaitu ahli statik Secara amnya, ahli yang diubah suai oleh statik menjadi atribut kelas, dan kaedah biasa dipanggil atribut contoh perbezaan yang besar)!
Pengenalan di atas adalah kawasan yang lebih biasa dalam JVM, dan pembahagian kawasan memori bagi sesetengah JVM tidak semestinya selaras dengan situasi sebenar dalam proses pelaksanaan JVM , kawasan Pembahagian adalah berbeza Mungkin terdapat perbezaan dalam versi JVM yang berbeza dari pengeluar yang berbeza Namun, bagi kami pengaturcara biasa, selagi kami tidak melaksanakan JVM, kami tidak perlu memahaminya dengan begitu mendalam bincangkan tentang perkara di atas. Hanya fahami beberapa bidang biasa!2. Mekanisme pemuatan kelas JVM
Di atas adalah proses pemuatan kelas yang terakhir adalah proses penggunaan dan tidak akan diperkenalkan saya memperkenalkan tiga langkah besar pertama:
Dalam fasa pemuatan, ia akan mula-mula mencari fail .class yang sepadan, kemudian buka dan baca (mengikut aliran bait) fail .class, dan pada mulanya menjana Objek kelas , ini berbeza daripada pemuatan kelas yang lengkap (Pemuatan kelas), jangan keliru
Format khusus fail kelas (jika anda ingin melaksanakan pengkompil Java, anda mesti membinanya! format ini , untuk melaksanakan JVM, anda mesti memuatkannya mengikut format ini!):
Jika anda memerhati format ini, anda boleh melihat bahawa fail .class menyatakan semua maklumat teras dalam .java fail, tetapi menyusunnya Format telah berubah, jadi proses pemuatan pada mulanya akan mengisi maklumat yang dibaca ke dalam objek kelas
Memautkan secara amnya adalah penubuhan berbilang entiti. Hubungan antara
Pengesahan ialah proses pengesahan, terutamanya untuk mengesahkan sama ada kandungan yang dibaca betul-betul sepadan dengan format yang dinyatakan dalam spesifikasi , jika didapati bahawa format data yang dibaca tidak memenuhi spesifikasi, pemuatan kelas akan gagal dan pengecualian akan dilemparkan
, memori akan diperuntukkan untuk setiap pembolehubah statik dan ditetapkan kepada nilai 0! 2.3.Resolusi (Resolusi)
, iaitu proses memulakan pemalar Pemalar dalam fail .class diletakkan di tengah, setiap pemalar akan mempunyai nombor, dan situasi awal dalam struktur dalam fail .class hanyalah nombor yang direkodkan. dan kemudian kandungan yang sepadan boleh ditemui berdasarkan nombor ini, dan kemudian diisikan dalam objek kelas! 3.Initialization
(mengikut kod yang ditulis), terutamanya untuk ahli statik 4. Soalan temuduga tipikal
Anda boleh cuba menulis sendiri hasil keluaran dahuluclass A { public A(){ System.out.println("A的构造方法"); } { System.out.println("A的构造代码块"); } static { System.out.println("A的静态代码块"); }}class B extends A{ public B(){ System.out.println("B的构造方法"); } { System.out.println("B的构造代码块"); } static { System.out.println("B的静态代码块"); }}public class Test extends B{ public static void main(String[] args) { new Test(); new Test(); }}
Untuk melakukan soalan sedemikian, anda perlu memahami beberapa prinsip utama:
输出结果: A的静态代码块 B的静态代码块 A的构造代码块 A的构造方法 B的构造代码块 B的构造方法 A的构造代码块 A的构造方法 B的构造代码块 B的构造方法
. Pemuat kelas di sini ialah objek yang disediakan khas oleh JVM Ia bertanggungjawab terutamanya untuk pemuatan kelas, jadi proses mencari fail juga bertanggungjawab untuk pemuat kelas Terdapat banyak tempat di mana fail .class boleh diletakkan, dan beberapa daripadanya mereka mesti diletakkan dalam direktori JDK , sesetengahnya diletakkan dalam direktori projek, dan sesetengahnya berada di lokasi khusus lain, jadi JVM menyediakan berbilang pemuat kelas, setiap pemuat kelas bertanggungjawab untuk sekeping, dan terdapat terutamanya 3 kelas lalai. pemuat:
Pertimbangkan untuk mencari java.lang.String:
Kemudian kelas java.lang.String boleh ditemui dalam perpustakaan standard, dan kemudian pemuat BootStrapClassLoader bertanggungjawab untuk proses pemuatan seterusnya dan proses carian telah tamat!
Pertimbangkan untuk mencari kelas Ujian yang anda tulis:
Apabila program bermula, ia akan mula-mula memasuki pemuat kelas ApplicationClassLoader
Pemuat kelas ApplicationClassLoader akan menyemak sama ada pemuat induknya telah dimuatkan Jika tidak, ia memanggil pemuat kelas induk ExtensionClassLoader
kelas ExtensionClassLoader Pemuat itu. sama ada pemuat induknya telah dimuatkan Jika tidak, ia akan memanggil pemuat kelas induk BootStrapClassLoader
Pemuat kelas BootStrapClassLoader juga akan menyemaknya Adakah pemuat induk telah dimuatkan, dan kemudian mendapatinya tiada bapa, jadi ia mengimbas direktori yang bertanggungjawab jika ia tidak mengimbas, ia akan kembali ke pemuat kanak-kanak untuk meneruskan pengimbasan
ExtensionClassLoader Imbas direktori yang anda bertanggungjawab. untuk, tetapi tiada apa yang ditemui. Kemudian kembali ke subloader dan teruskan mengimbas
ApplicationClassLoader juga mengimbas direktori yang anda bertanggungjawab, dan kelas yang anda tulis berada dalam direktori projek anda sendiri. Muat turun, jadi ia boleh ditemui, dan kemudian pemuatan kelas seterusnya diselesaikan oleh ApplicationClassLoad Pada masa ini, pautan mencari direktori telah tamat~~ (Selain itu, jika ApplicationClassLoader tidak dijumpai, ia akan membuang pengecualian ClassNotFoundException) <.>
Apabila kelas ditulis oleh pengaturcara mempunyai nama kelas berkelayakan sepenuhnya yang sama Sekarang, anda juga boleh berjaya memuatkan kelas dalam perpustakaan standard dan bukannya kelas yang ditulis sendiri!!! Selain itu, jika ia adalah pemuat kelas tersuai, sekiranya anda mematuhi model delegasi ibu bapa ini?
Jawapan Ia boleh dipatuhi atau tidak, ia bergantung terutamanya pada keperluan Contohnya, jika Tomcat memuatkan kelas dalam aplikasi web, ia tidak akan dipatuhi, kerana mustahil untuk mencarinya. pemuat kelas yang mematuhi perkara di atas!
mekanisme pengumpulan sampah (GC) dalam JVM secara amnya melibatkan permohonan memori semasa menulis kod, seperti sebagai mencipta pembolehubah, objek baharu dan memanggil kaedah Memuatkan kelas... Masa memohon memori secara amnya jelas (anda perlu memohon memori jika anda perlu menyimpan data tertentu), tetapi masa untuk melepaskan memori. tidak begitu jelas, dan ia tidak akan berfungsi jika anda melepaskannya terlalu awal (jika anda masih perlu menggunakannya, hasilnya telah dikeluarkan, yang bermaksud bahawa tiada memori tersedia, dan data mempunyai "tiada ke mana untuk pergi"), ia tidak akan berfungsi jika ia dikeluarkan lewat (lewat dikeluarkan, sejumlah besar penimbunan berkemungkinan akan secara beransur-ansur menjadikan memori tersedia secara beransur-ansur Jika ia menjadi kurang, kemungkinan besar akan berlaku masalah kebocoran memori (iaitu, terdapat tiada ingatan untuk digunakan), jadi pelepasan memori mestilah betul ! yang sangat mengurangkan beban mental pengaturcara, tetapi kutipan sampah juga mempunyai kelemahan
: ① Penggunaan overhed tambahan (lebih banyak sumber digunakan ② Ia mungkin menjejaskan kelancaran program (kutipan sampah sering memperkenalkan STW masalah (Stop The World))
Dan pengiraan rujukan Idea khusus ialah untuk setiap objek, sejumlah kecil memori tambahan akan diperkenalkan untuk menyimpan bilangan rujukan objek ini menunjuk kepadanyaPembilang program: Memori ini bersaiz tetap dan tidak melibatkan pelepasan, jadi tidak ada keperluan untuk GC; dikeluarkan secara automatik, dan GC tidak diperlukan;
Timbunan: Ini adalah memori yang paling memerlukan GC Sebilangan besar memori dalam kod umum ;Ini bukan penyelesaian yang diterima pakai dalam Java, ia adalah penyelesaian untuk Python dan bahasa lain, jadi saya akan memperkenalkannya secara ringkas di sini tanpa terlalu banyak~
- Antara ketiga-tiga kawasan ini yang manakah perlu dilepaskan? tidak akan ada keadaan separuh objek dalam GC Oleh itu,
- unit asas pengumpulan sampah ialah objek
, bukan bait! perlu dilepaskan hanya apabila kelas dipunggah. Operasi memunggah adalah frekuensi yang sangat rendah, jadi ia hampir tidak melibatkan GC!
Mari kita lihat dengan lebih dekat cara mengitar semula: 1. Cari sampah/tentukan sampahPada masa ini terdapat dua penyelesaian arus perdana:- 1.1 Berdasarkan pengiraan rujukan
Analisis kebolehcapaian ialah Penyelesaian yang diterima pakai oleh Java adalah untuk. imbas objek dalam keseluruhan ruang memori dengan kerap melalui beberapa utas tambahan , dengan beberapa kedudukan permulaan (GCRoots), dan kemudian ia serupa dengan traversal depth-first (boleh dibayangkan sebagai pokok), tandakan semua objek yang boleh diakses (objek yang ditanda ialah objek yang boleh dicapai), dan objek yang tidak ditanda adalah objek yang tidak boleh dicapai, iaitu sampah, dan harus Dikeluarkan
GCRots di sini (melintasi dari lokasi ini):
Oleh itu, kelebihan analisis kebolehcapaian ialah ia menyelesaikan kelemahan pengiraan rujukan: penggunaan ruang rendah dan rujukan bulat;Kekurangan analisis kebolehcapaian juga jelas: Overhed sistem adalah tinggi, dan melintasinya sekali mungkin lambat~
Jadi mencari sampah juga sangat mudah untuk mengesahkan sama ada objek ini akan digunakan pada masa hadapan, lihat jika terdapat sebarang rujukan yang menunjuk kepadanya , patutkah dilepaskan?
Sekarang sudah jelas apa itu sampah, langkah seterusnya ialah mengitar semula sampah. Mari lihat!
Teg di sini adalah kebolehcapaian Proses analisis, dan pembersihan adalah untuk melepaskan. ingatan Anggapkan bahawa di atas adalah sekeping memori, dan kawasan yang ditandakan mewakili sampah Jika anda melepaskannya secara langsung pada masa ini, walaupun memori dikembalikan kepada sistem, memori yang dikeluarkan adalah diskret , dan masalah yang disebabkan oleh ini ialah "pemecahan memori". Mungkin terdapat banyak memori percuma adalah mungkin bahawa aplikasi gagal di sini (kerana 500MB yang akan digunakan adalah memori berterusan, dan memori yang digunakan untuk setiap kali adalah ruang memori berterusan, dan 1G di sini mungkin merupakan jumlah serpihan berbilang), jadi masalah ini sebenarnya Ia sangat mempengaruhi perjalanan program
Memandangkan strategi tanda jelas di atas boleh menyebabkan masalah pemecahan memori, memperkenalkan algoritma penyalinan untuk menyelesaikan masalah ini Soalan
Di atas adalah sekeping ingatan Strategi algoritma salin adalah menggunakan separuh daripada memori, buang separuh, dan tidak menggunakan semua itu bahagian bukan sampah kepada separuh yang lain (salinan ini Ia diproses secara dalaman oleh JVM, tidak perlu risau), dan kemudian semua memori yang digunakan sebelum ini dikeluarkan, supaya masalah pemecahan memori mudah diselesaikan! algoritma penyalinan mempunyai dua masalah besar:
peningkatan lanjut pada algoritma penyalinan!
Strategi menanda dan menyusun ialahKumpulkan memori yang bukan sampah bersama-sama, dan kemudian lepaskan semua memori seterusnya
Ia serupa dengan operasi memadam elemen tengah dalam urutan jadual. Terdapat proses bergerak! Penyelesaian ini mempunyai penggunaan ruang yang tinggi , tetapi masih tiada cara untuk menyelesaikan masalah overhed tinggi elemen penyalinan/pergerakan!
Walaupun ketiga-tiga penyelesaian di atas boleh menyelesaikan masalahnya, semuanya mempunyai kekurangan masing-masing, jadi sebenarnya, pelaksanaan dalam JVM akan Gabungan pelbagai penyelesaian dipanggil "kitar semula generasi"!!!
2.4 Kitar semula generasi
Ini adalah keseluruhan proses kitar semula generasi!
Pencarian sampah dan pelepasan sampah di atas hanyalah idea algoritma, bukan proses pelaksanaan sebenar modul algoritma di atas ialah "pengumpul sampah". beberapa pengumpul sampah khusus:
Pengumpul bersiri ialah pengumpul sampah untuk generasi baru, dan Pengumpul Bersiri Lama ialah Pengumpul sampah yang disediakan untuk generasi lama. Kedua-dua pengumpul ini mengumpul secara bersiri, dan apabila mengimbas dan melepaskan sampah, benang perniagaan perlu berhenti berfungsi, jadi dengan cara ini, imbasan penuh dan pelepasannya perlahan Dan ia juga boleh menghasilkan STW yang serius 3.2. Pengumpul ParNew, Pengumpul Parallel Scavenge dan Pengumpul Lama Parallel
Pengumpul di atas adalah tinggalan sejarah, iaitu kaedah pengumpulan sampah yang lebih lama Di samping itu, Memperkenalkan dua pengumpul sampah yang dikemas kini!
3.3.Pengumpul CMS
, Java8 menggunakan pengumpul CMS Berikut adalah pengenalan ringkas kepada proses pengumpul CMS:
Permulaan. tanda: sangat pantas, akan menyebabkan STW pendek (cuma cari GCRoots);telah digunakan sejak Java11. Pengumpul ini membahagikan keseluruhan memori kepada banyak wilayah kecil, dan menandakan wilayah ini secara berbeza Beberapa Wilayah menyimpan objek generasi baru, dan beberapa Kawasan menyimpan objek generasi lama, apabila mengimbas, beberapa Wilayah diimbas sekaligus (. tidak perlu melengkapkan imbasan dalam satu pusingan GC, dan ia perlu diimbas beberapa kali). Ini akan memberi kesan pada kod perniagaan Kedua-dua pengumpul baharu ini adalah untuk memecahkannya kepada beberapa bahagian G1 pada masa ini boleh dioptimumkan untuk menjadikan masa jeda STW kurang daripada 1ms, yang boleh diterima sepenuhnya , dan idea pengumpulan sampah di atas adalah sangat penting!!!Kajian yang disyorkan: "
tutorial video java"
Atas ialah kandungan terperinci Ringkasan pengetahuan Java dan penjelasan terperinci JVM. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!