Pertama sekali, jelaskan beberapa konsep kod Java yang dijalankan dalam jvm, dan kawasan memori jvm dibahagikan kepada beberapa modul:
Daftar Kaunter Program: Kaunter program ialah kawasan memori yang agak kecil yang digunakan untuk menunjukkan baris kod bait yang dilaksanakan oleh utas semasa telah dilaksanakan Ia boleh difahami sebagai Nombor baris penunjuk untuk benang semasa. Apabila jurubahasa bytecode berfungsi, ia akan mengambil arahan pernyataan dengan menukar nilai kaunter ini.
JVM Stack: Apabila setiap kaedah thread dilaksanakan, bingkai tindanan (Statck Frame) akan dibuat dan jadual pembolehubah setempat disimpan dalam bingkai tindanan , stesen operasi , pautan dinamik, kaedah keluar, dsb. Apabila kaedah dipanggil, bingkai tindanan ditolak ke dalam tindanan JVM Apabila pelaksanaan kaedah selesai, bingkai tindanan akan muncul daripada tindanan.
Timbunan Kaedah Asli: Timbunan kaedah asli adalah sama dengan timbunan mesin maya dari segi fungsi, mekanisme pengendalian, jenis pengecualian, dll. Satu-satunya perbezaan ialah: timbunan mesin maya ialah Laksanakan kaedah Java, manakala tindanan kaedah tempatan digunakan untuk melaksanakan kaedah asli Dalam banyak mesin maya (seperti mesin maya HotSpot lalai Sun), tindanan kaedah tempatan dan tindanan mesin maya digunakan bersama.
Timbunan: Kawasan timbunan ialah kawasan paling penting untuk memahami mekanisme Java GC, tiada bar. Kawasan timbunan ialah sekeping memori terbesar yang diuruskan oleh JVM Kawasan timbunan juga merupakan kawasan ingatan utama yang diuruskan oleh mekanisme GC Java Kawasan timbunan dikongsi oleh semua benang dan dicipta apabila mesin maya dimulakan. Kawasan timbunan wujud untuk menyimpan contoh objek Pada dasarnya, semua objek diperuntukkan memori pada kawasan timbunan (tetapi dalam teknologi moden, ini tidak begitu mutlak, dan beberapa objek diperuntukkan secara langsung pada timbunan).
Kaedah Kawasan: (juga dikenali sebagai generasi kekal Kawasan kaedah ialah kawasan yang dikongsi oleh setiap benang dan digunakan untuk menyimpan maklumat kelas yang telah dimuatkan oleh mesin maya (). iaitu Maklumat yang perlu dimuatkan semasa memuatkan kelas, termasuk versi, medan, kaedah, antara muka dan maklumat lain), pemalar akhir, pembolehubah statik, kod yang disusun oleh pengkompil secara on-the-fly, dsb.
Memori Langsung: Memori langsung bukan memori yang diuruskan oleh JVM Ia boleh difahami bahawa memori langsung ialah memori mesin selain daripada JVM Sebagai contoh, jika anda mempunyai memori 4G, JVM menduduki 1G, dan baki 3G adalah memori langsung Terdapat kaedah peruntukan memori berdasarkan saluran dan penimbal dalam JDK Pustaka fungsi asli yang dilaksanakan dalam bahasa C diperuntukkan dalam ingatan langsung, dan disimpan dalam DirectByteBuffer dalam timbunan JVM untuk rujukan. . Memandangkan memori langsung dihadkan oleh memori mesin, pengecualian OutOfMemoryError juga mungkin berlaku.
Setelah memahami konsep asas ini, mari kita lihat bahagian yang meragui penyoal. Sebenarnya, apa yang ditanyakan oleh penanya ialah bagaimana rujukan objek dilaksanakan di Jawa. Mengapa anda boleh mentakrifkan rujukan anda sendiri semasa menentukan kelas Pada masa yang sama, jika anda membuat rujukan ini, bukankah ia akan membawa kepada rujukan pekeliling yang tidak terhingga?
Jangan risau, mari kita analisa dahulu cara rujukan dilaksanakan dalam Java:
Akses rujukan Java melibatkan tiga kawasan ingatan: JVM tindanan, timbunan dan kawasan kaedah.
Ambil rujukan pembolehubah tempatan yang paling mudah: Object obj = new Object() sebagai contoh:
Obj objek mewakili rujukan setempat, yang disimpan dalam jadual pembolehubah setempat bagi timbunan JVM dan mewakili data jenis rujukan;
Objek() baharu disimpan dalam timbunan sebagai data objek contoh
Alamat maklumat jenis kelas Objek (antara muka, kaedah, medan, jenis objek, dll.) juga direkodkan dalam timbunan dan data yang dilaksanakan oleh alamat ini disimpan dalam kawasan kaedah;
Terdapat banyak kaedah pelaksanaan khusus, pemegang adalah salah satu daripadanya, dan hubungannya adalah seperti yang ditunjukkan dalam rajah.
Anda harus memahaminya apabila anda melihat ini. Maklumat kelas itu sendiri, data contoh kelas, dan maklumat rujukan yang menunjuk ke objek diletakkan di kawasan kaedah, kawasan timbunan, dan kawasan timbunan java masing-masing.
Dalam contoh subjek, urutan pemuatan java adalah seperti berikut:
jvm mula-mula memuatkan takrifan kelas dalam kawasan kaedah (tetapi kelas itu tidak dibuat seketika pada masa ini)
Oleh kerana
ialah pembolehubah statik, pembolehubah ini juga akan dimuatkan ke dalam kawasan kaedah apabila jvm membaca definisi kawasan kaedah untuk kali pertama.
public static final Direction FRONT = new Direction();
Pada masa yang sama, ini juga bermakna bahawa semasa memuatkan pembolehubah ini, tika kelas ini juga dibuat seketika dalam kawasan timbunan.
Perhatikan perkara utama di sini, kerana pembolehubah FRONT ialah pembolehubah statik, dan definisi kelas yang dimuatkan hanya akan dimuatkan sekali, jadi pembolehubah statik ini hanya boleh dimuatkan sekali. Ia tidak menyebabkan limpahan tindanan disebabkan instantiasi berulang rujukan bulat seperti pembolehubah bukan statik.
Beritahu saya pemahaman anda, mengapa anda tidak boleh mencipta objek anda sendiri dalam kelas? Selepas menambah statik, pembolehubah ini menjadi atribut kelas dan hanya akan dibuat sekali.
Sebab untuk menggunakan kelas dalam: Setiap kelas dalam boleh mewarisi secara bebas daripada pelaksanaan (antara muka), jadi sama ada kelas luar telah mewarisi pelaksanaan (antara muka), ia tidak mempunyai kesan pada kelas dalam. Malah, kelas dalam melaksanakan "warisan berbilang" dengan berkesan, iaitu, kelas dalam membenarkan pewarisan berbilang jenis bukan antara muka.
Kami tahu bahawa kelas dalaman secara automatik mempunyai akses kepada semua ahli kelas luar, jadi bagaimana ini dilakukan? Apabila objek kelas luar mencipta objek kelas dalam, objek kelas dalam mesti secara rahsia menangkap rujukan kepada objek kelas luar itu. Kemudian, apabila anda mengakses ahli kelas luar, anda menggunakan rujukan itu untuk memilih ahli kelas luar. Sudah tentu butiran ini dikendalikan oleh pengkompil, dan kelas dalaman di sini bukan statik. Jika kelas tidak boleh mencipta objek kelasnya sendiri, maka apakah kegunaan kelas anda? Ah, hahahaha, gurau je
Pertama sekali, jelaskan beberapa konsep kod Java yang dijalankan dalam jvm, dan kawasan memori jvm dibahagikan kepada beberapa modul:
Daftar Kaunter Program: Kaunter program ialah kawasan memori yang agak kecil yang digunakan untuk menunjukkan baris kod bait yang dilaksanakan oleh utas semasa telah dilaksanakan Ia boleh difahami sebagai Nombor baris penunjuk untuk benang semasa. Apabila jurubahasa bytecode berfungsi, ia akan mengambil arahan pernyataan dengan menukar nilai kaunter ini.
JVM Stack: Apabila setiap kaedah thread dilaksanakan, bingkai tindanan (Statck Frame) akan dibuat dan jadual pembolehubah setempat disimpan dalam bingkai tindanan , stesen operasi , pautan dinamik, kaedah keluar, dsb. Apabila kaedah dipanggil, bingkai tindanan ditolak ke dalam tindanan JVM Apabila pelaksanaan kaedah selesai, bingkai tindanan akan muncul daripada tindanan.
Timbunan Kaedah Asli: Timbunan kaedah asli adalah sama dengan timbunan mesin maya dari segi fungsi, mekanisme pengendalian, jenis pengecualian, dll. Satu-satunya perbezaan ialah: timbunan mesin maya ialah Laksanakan kaedah Java, manakala tindanan kaedah tempatan digunakan untuk melaksanakan kaedah asli Dalam banyak mesin maya (seperti mesin maya HotSpot lalai Sun), tindanan kaedah tempatan dan tindanan mesin maya digunakan bersama.
Timbunan: Kawasan timbunan ialah kawasan paling penting untuk memahami mekanisme Java GC, tiada bar. Kawasan timbunan ialah sekeping memori terbesar yang diuruskan oleh JVM Kawasan timbunan juga merupakan kawasan ingatan utama yang diuruskan oleh mekanisme GC Java Kawasan timbunan dikongsi oleh semua benang dan dicipta apabila mesin maya dimulakan. Kawasan timbunan wujud untuk menyimpan contoh objek Pada dasarnya, semua objek diperuntukkan memori pada kawasan timbunan (tetapi dalam teknologi moden, ini tidak begitu mutlak, dan beberapa objek diperuntukkan secara langsung pada timbunan).
Kaedah Kawasan: (juga dikenali sebagai generasi kekal Kawasan kaedah ialah kawasan yang dikongsi oleh setiap benang dan digunakan untuk menyimpan maklumat kelas yang telah dimuatkan oleh mesin maya (). iaitu Maklumat yang perlu dimuatkan semasa memuatkan kelas, termasuk versi, medan, kaedah, antara muka dan maklumat lain), pemalar akhir, pembolehubah statik, kod yang disusun oleh pengkompil secara on-the-fly, dsb.
Memori Langsung: Memori langsung bukan memori yang diuruskan oleh JVM Ia boleh difahami bahawa memori langsung ialah memori mesin selain daripada JVM Sebagai contoh, jika anda mempunyai memori 4G, JVM menduduki 1G, dan baki 3G adalah memori langsung Terdapat kaedah peruntukan memori berdasarkan saluran dan penimbal dalam JDK Pustaka fungsi asli yang dilaksanakan dalam bahasa C diperuntukkan dalam ingatan langsung, dan disimpan dalam DirectByteBuffer dalam timbunan JVM untuk rujukan. . Memandangkan memori langsung dihadkan oleh memori mesin, pengecualian OutOfMemoryError juga mungkin berlaku.
Setelah memahami konsep asas ini, mari kita lihat bahagian yang meragui penyoal. Sebenarnya, apa yang ditanyakan oleh penanya ialah bagaimana rujukan objek dilaksanakan di Jawa. Mengapa anda boleh mentakrifkan rujukan anda sendiri semasa menentukan kelas Pada masa yang sama, jika anda membuat rujukan ini, bukankah ia akan membawa kepada rujukan pekeliling yang tidak terhingga?
Jangan risau, mari kita analisa dahulu cara rujukan dilaksanakan dalam Java:
Akses rujukan Java melibatkan tiga kawasan ingatan: JVM tindanan, timbunan dan kawasan kaedah.
Ambil rujukan pembolehubah tempatan yang paling mudah: Object obj = new Object() sebagai contoh:
Obj objek mewakili rujukan setempat, yang disimpan dalam jadual pembolehubah setempat bagi timbunan JVM dan mewakili data jenis rujukan;
Anda harus memahaminya apabila anda melihat ini. Maklumat kelas itu sendiri, data contoh kelas, dan maklumat rujukan yang menunjuk ke objek diletakkan di kawasan kaedah, kawasan timbunan, dan kawasan timbunan java masing-masing.
Dalam contoh subjek, urutan pemuatan java adalah seperti berikut:
jvm mula-mula memuatkan takrifan kelas dalam kawasan kaedah (tetapi kelas itu tidak dibuat seketika pada masa ini)
Oleh kerana - ialah pembolehubah statik, pembolehubah ini juga akan dimuatkan ke dalam kawasan kaedah apabila jvm membaca definisi kawasan kaedah untuk kali pertama.
Pada masa yang sama, ini juga bermakna bahawa semasa memuatkan pembolehubah ini, tika kelas ini juga dibuat seketika dalam kawasan timbunan. -
Perhatikan perkara utama di sini, kerana pembolehubah FRONT ialah pembolehubah statik, dan definisi kelas yang dimuatkan hanya akan dimuatkan sekali, jadi pembolehubah statik ini hanya boleh dimuatkan sekali. Ia tidak menyebabkan limpahan tindanan disebabkan instantiasi berulang rujukan bulat seperti pembolehubah bukan statik.
public static final Direction FRONT = new Direction();
Syorkan anda membaca jawapan R
Beritahu saya pemahaman anda, mengapa anda tidak boleh mencipta objek anda sendiri dalam kelas?
Selepas menambah statik, pembolehubah ini menjadi atribut kelas dan hanya akan dibuat sekali.
Jika anda tidak boleh mencipta sendiri, maka kelas lain tidak boleh. Dalam kes ini, bagaimana untuk membuat instantiate kelas ini...
Corak Rekaan: Corak Singleton
Intipatinya ialah kekurangan pemahaman tentang pengaturcaraan berorientasikan objek dalam Java. Lihat 23 corak reka bentuk dan anda mungkin faham
Pembina juga merupakan kaedah.
Kaedah dengan
private
hak akses adalah peribadi dan hanya boleh dilihat oleh kelas ini.Jadi, kelas ini boleh membuat instantiate objek dengan memanggil pembina dengan hak akses
private
.Sebab untuk menggunakan kelas dalam: Setiap kelas dalam boleh mewarisi secara bebas daripada pelaksanaan (antara muka), jadi sama ada kelas luar telah mewarisi pelaksanaan (antara muka), ia tidak mempunyai kesan pada kelas dalam. Malah, kelas dalam melaksanakan "warisan berbilang" dengan berkesan, iaitu, kelas dalam membenarkan pewarisan berbilang jenis bukan antara muka.
Kami tahu bahawa kelas dalaman secara automatik mempunyai akses kepada semua ahli kelas luar, jadi bagaimana ini dilakukan? Apabila objek kelas luar mencipta objek kelas dalam, objek kelas dalam mesti secara rahsia menangkap rujukan kepada objek kelas luar itu. Kemudian, apabila anda mengakses ahli kelas luar, anda menggunakan rujukan itu untuk memilih ahli kelas luar. Sudah tentu butiran ini dikendalikan oleh pengkompil, dan kelas dalaman di sini bukan statik.
Jika kelas tidak boleh mencipta objek kelasnya sendiri, maka apakah kegunaan kelas anda? Ah, hahahaha, gurau je