CodeGym/Kursus Java/Modul 3/Memori dalam JVM

Memori dalam JVM

Tahap, pelajaran
Tersedia

Memahami Memori dalam JVM

Seperti yang anda sedia maklum, JVM menjalankan program Java dalam dirinya sendiri. Seperti mana-mana mesin maya, ia mempunyai sistem organisasi memori sendiri.

Susun atur memori dalaman menunjukkan cara aplikasi Java anda berfungsi. Dengan cara ini, kesesakan dalam pengendalian aplikasi dan algoritma dapat dikenal pasti. Mari lihat bagaimana ia berfungsi.

Memahami Memori dalam JVM

Penting! Model Java asal tidak cukup baik, jadi ia telah disemak dalam Java 1.5. Versi ini digunakan sehingga hari ini (Java 14+).

Timbunan benang

Model memori Java yang digunakan secara dalaman oleh JVM membahagikan memori kepada tindanan dan timbunan benang. Mari kita lihat model memori Java, secara logik dibahagikan kepada blok:

Timbunan benang

Semua benang yang berjalan dalam JVM mempunyai timbunan mereka sendiri . Tindanan pula menyimpan maklumat tentang kaedah yang dipanggil oleh benang. Saya akan memanggil ini "timbunan panggilan". Tindanan panggilan disambung semula sebaik sahaja benang melaksanakan kodnya.

Tindanan benang mengandungi semua pembolehubah tempatan yang diperlukan untuk melaksanakan kaedah pada tindanan benang. Sesuatu benang hanya boleh mengakses tindanannya sendiri. Pembolehubah setempat tidak kelihatan kepada utas lain, hanya kepada utas yang menciptanya. Dalam keadaan di mana dua utas melaksanakan kod yang sama, kedua-duanya mencipta pembolehubah tempatan mereka sendiri. Oleh itu, setiap thread mempunyai versi tersendiri bagi setiap pembolehubah tempatan.

Semua pembolehubah tempatan jenis primitif ( boolean , byte , short , char , int , long , float , double ) disimpan sepenuhnya pada tindanan benang dan tidak kelihatan kepada benang lain. Satu utas boleh menghantar salinan pembolehubah primitif ke utas lain, tetapi tidak boleh berkongsi pembolehubah tempatan primitif.

Timbunan

Timbunan mengandungi semua objek yang dibuat dalam aplikasi anda, tanpa mengira benang yang mencipta objek itu. Ini termasuk pembalut jenis primitif (contohnya, Byte , Integer , Long , dan sebagainya). Tidak kira sama ada objek itu dicipta dan diberikan kepada pembolehubah tempatan atau dicipta sebagai pembolehubah ahli objek lain, ia disimpan pada timbunan.

Di bawah ialah gambar rajah yang menggambarkan timbunan panggilan dan pembolehubah setempat (ia disimpan pada tindanan) serta objek (ia disimpan pada timbunan):

Timbunan

Dalam kes di mana pembolehubah tempatan adalah daripada jenis primitif, ia disimpan pada timbunan benang.

Pembolehubah tempatan juga boleh menjadi rujukan kepada objek. Dalam kes ini, rujukan (pembolehubah tempatan) disimpan pada tindanan benang, tetapi objek itu sendiri disimpan pada timbunan.

Objek mengandungi kaedah, kaedah ini mengandungi pembolehubah tempatan. Pembolehubah tempatan ini juga disimpan pada tindanan benang, walaupun objek yang memiliki kaedah itu disimpan pada timbunan.

Pembolehubah ahli objek disimpan pada timbunan bersama dengan objek itu sendiri. Ini benar apabila pembolehubah ahli adalah daripada jenis primitif dan apabila ia adalah rujukan objek.

Pembolehubah kelas statik juga disimpan pada timbunan bersama dengan definisi kelas.

Interaksi dengan objek

Objek pada timbunan boleh diakses oleh semua benang yang mempunyai rujukan kepada objek. Jika benang mempunyai akses kepada objek, maka ia boleh mengakses pembolehubah objek. Jika dua utas memanggil kaedah pada objek yang sama pada masa yang sama, kedua-duanya akan mempunyai akses kepada pembolehubah ahli objek, tetapi setiap utas akan mempunyai salinan pembolehubah tempatannya sendiri.

Interaksi dengan objek (timbunan)

Dua benang mempunyai satu set pembolehubah tempatan.Pembolehubah Setempat 2menunjuk ke objek kongsi pada timbunan (Objek 3). Setiap benang mempunyai salinan pembolehubah tempatannya sendiri dengan rujukannya sendiri. Rujukan mereka adalah pembolehubah tempatan dan oleh itu disimpan pada susunan benang. Walau bagaimanapun, dua rujukan berbeza menunjuk kepada objek yang sama pada timbunan.

Sila ambil perhatian bahawa jeneralObjek 3mempunyai pautan keObjek 2DanObjek 4sebagai pembolehubah ahli (ditunjukkan dengan anak panah). Melalui pautan ini, dua utas boleh mengaksesObjek 2DanObjek4.

Rajah juga menunjukkan pembolehubah tempatan (pembolehubah tempatan 1daripada kaedahDua ). Setiap salinannya mengandungi rujukan berbeza yang menunjuk kepada dua objek berbeza (Objek 1DanObjek 5) dan bukan yang sama. Secara teorinya, kedua-dua utas boleh mengakses kedua-duanyaObjek 1, jadi kepadaObjek 5jika mereka mempunyai rujukan kepada kedua-dua objek ini. Tetapi dalam rajah di atas, setiap benang hanya mempunyai rujukan kepada salah satu daripada dua objek.

Contoh interaksi dengan objek

Mari lihat bagaimana kita boleh menunjukkan kerja dalam kod:

public class MySomeRunnable implements Runnable() {

    public void run() {
        one();
    }

    public void one() {
        int localOne = 1;

        Shared localTwo = Shared.instance;

        //... do something with local variables

        two();
    }

    public void two() {
        Integer localOne = 2;

        //... do something with local variables
    }
}
public class Shared {

    // store an instance of our object in a variable

    public static final Shared instance = new Shared();

    // member variables pointing to two objects on the heap

    public Integer object2 = new Integer(22);
    public Integer object4 = new Integer(44);
}

Kaedah run() memanggil kaedah one() , dan one() pula memanggil two() .

Kaedah one() mengisytiharkan pembolehubah tempatan primitif (localOne) jenis int dan pembolehubah tempatan (tempatanDua), yang merupakan rujukan kepada objek.

Setiap thread yang melaksanakan kaedah one() akan mencipta salinannya sendirilocalOneDantempatanDuadalam timbunan anda. PembolehubahlocalOneakan dipisahkan sepenuhnya antara satu sama lain, berada pada timbunan setiap benang. Satu utas tidak dapat melihat perubahan yang dilakukan oleh utas lain kepada salinannyalocalOne.

Setiap thread yang melaksanakan kaedah one() juga mencipta salinannya sendiritempatanDua. Namun, dua salinan berbezatempatanDuaakhirnya menunjuk ke objek yang sama pada timbunan. Hakikatnya ialahtempatanDuamenunjuk kepada objek yang dirujuk oleh pembolehubah statikcontoh. Terdapat hanya satu salinan pembolehubah statik, dan salinan itu disimpan pada timbunan.

Jadi kedua-dua salinantempatanDuaakhirnya menunjuk ke contoh Dikongsi yang sama . Contoh Dikongsi juga disimpan pada timbunan. Ia sepadanObjek 3dalam rajah di atas.

Ambil perhatian bahawa kelas Kongsi juga mengandungi dua pembolehubah ahli. Pembolehubah ahli itu sendiri disimpan pada timbunan bersama dengan objek. Dua pembolehubah ahli menunjuk kepada dua objek lainInteger. Objek integer ini sepadan denganObjek 2DanObjek 4pada rajah.

Juga ambil perhatian bahawa kaedah two() mencipta pembolehubah tempatan bernamalocalOne. Pembolehubah tempatan ini adalah rujukan kepada objek jenis Integer . Kaedah menetapkan pautanlocalOneuntuk menunjuk kepada contoh Integer baharu . Pautan akan disimpan dalam salinannyalocalOneuntuk setiap utas. Dua kejadian Integer akan disimpan pada timbunan, dan kerana kaedah mencipta objek Integer baharu setiap kali ia dilaksanakan, dua utas yang melaksanakan kaedah ini akan mencipta kejadian Integer yang berasingan . Mereka sepadanObjek 1DanObjek 5dalam rajah di atas.

Perhatikan juga dua pembolehubah ahli dalam kelas Kongsi jenis Integer , yang merupakan jenis primitif. Oleh kerana pembolehubah ini adalah pembolehubah ahli, ia masih disimpan pada timbunan bersama dengan objek. Hanya pembolehubah tempatan disimpan pada tindanan benang.

Komen
  • Popular
  • Baru
  • Tua
Anda mesti log masuk untuk meninggalkan ulasan
Halaman ini tidak mempunyai sebarang ulasan lagi