Artikel ini terutama menjelaskan prinsip kerjanya secara rinci dengan menganalisis tumpukan, heap, dan kumpulan alokasi memori Java yang konstan.
1. Prototipe memori mesin virtual Java
Daftar: Kami tidak memiliki kendali atas program. Stack: menyimpan tipe data dasar dan referensi objek, namun objek itu sendiri tidak disimpan di tumpukan, tetapi disimpan di heap. Heap: menyimpan data yang dihasilkan dengan domain statis : disimpan dalam objek. Kumpulan konstan anggota statis yang didefinisikan dengan statis: menyimpan konstanta non-RAM: ruang penyimpanan permanen seperti hard disk.
2. Kolam konstan
Kumpulan konstan mengacu pada kumpulan konstan yang ditentukan pada waktu kompilasi dan disimpan dalam memori yang dikompilasi. Beberapa data dalam file kelas. Selain nilai konstanta (final) yang berisi berbagai tipe dasar (seperti int, long, dll.) dan tipe objek (seperti String dan array) yang ditentukan dalam kode, juga berisi beberapa referensi simbolik dalam bentuk teks , seperti:
1. Nama kelas dan antarmuka yang sepenuhnya memenuhi syarat;
2. Nama field dan deskriptornya;
3. Metode, nama dan deskriptor.
Mesin virtual harus mempertahankan kumpulan konstan untuk setiap jenis yang dimuat. Kumpulan konstanta adalah kumpulan konstanta terurut yang digunakan oleh tipe ini, termasuk konstanta langsung (konstanta string, integer, dan floating point) dan referensi simbolis ke tipe, bidang, dan metode lain. Untuk konstanta String, nilainya ada di kumpulan konstanta. Kumpulan konstan di JVM ada dalam bentuk tabel di memori. Untuk tipe String, ada tabel CONSTANT_String_info dengan panjang tetap yang digunakan untuk menyimpan nilai string literal. Catatan: Tabel ini hanya menyimpan nilai string literal, bukan simbol . Karena itu, Anda harus memiliki pemahaman yang jelas tentang lokasi penyimpanan nilai string di kumpulan konstan. Ketika program dijalankan, kumpulan konstan akan disimpan di Area Metode, bukan di heap.
3. Tumpukan alokasi memori Java
Unit dasar tumpukan adalah bingkai (atau bingkai tumpukan): setiap kali thread Java berjalan, mesin virtual Java mengalokasikan tumpukan Java ke thread tersebut. Saat thread menjalankan metode Java tertentu, thread tersebut mendorong frame ke dalam tumpukan Java. Frame ini digunakan untuk menyimpan parameter, variabel lokal, operan, hasil operasi perantara, dll. Ketika metode ini selesai dieksekusi, frame akan dikeluarkan dari tumpukan. Semua data di tumpukan Java bersifat pribadi, dan tidak ada thread lain yang dapat mengakses data tumpukan thread tersebut. Beberapa tipe dasar data variabel dan variabel referensi objek yang ditentukan dalam fungsi dialokasikan dalam memori tumpukan fungsi. Ketika suatu variabel didefinisikan dalam blok kode, Java mengalokasikan ruang memori untuk variabel tersebut di tumpukan. Ketika variabel keluar dari cakupan, Java akan secara otomatis melepaskan ruang memori yang dialokasikan untuk variabel tersebut, dan ruang memori tersebut dapat segera digunakan. digunakan untuk keperluan lain.
4. Tumpukan alokasi memori Java
Heap di mesin virtual Java digunakan untuk menyimpan objek dan array yang baru dibuat. Memori yang dialokasikan di heap dikelola oleh mekanisme pengumpulan sampah otomatis dari mesin virtual Java. Sederhananya, dibandingkan dengan tumpukan, heap terutama digunakan untuk menyimpan objek Java, dan tumpukan terutama digunakan untuk menyimpan referensi objek... Setelah array atau objek dibuat di heap, variabel khusus juga dapat berupa didefinisikan dalam tumpukan, sehingga Nilai variabel ini dalam tumpukan sama dengan alamat pertama array atau objek di memori heap. Variabel dalam tumpukan ini menjadi variabel referensi array atau objek. Variabel referensi setara dengan memberi nama pada array atau objek. Anda kemudian dapat menggunakan variabel referensi di tumpukan untuk mengakses array atau objek di tumpukan dalam program. Variabel referensi setara dengan memberi nama pada array atau objek.
Variabel referensi adalah variabel biasa yang dialokasikan pada tumpukan ketika didefinisikan. Variabel referensi dilepaskan setelah program berjalan di luar cakupannya. Array dan objek itu sendiri dialokasikan di heap. Sekalipun program berjalan di luar blok kode tempat pernyataan menggunakan new untuk menghasilkan array atau objek berada, memori yang ditempati oleh array dan objek itu sendiri tidak akan dilepaskan objek tidak memiliki variabel referensi yang menunjuk ke sana, menjadi sampah dan tidak dapat digunakan lagi, namun masih menempati ruang memori dan akan dikumpulkan (dilepaskan) oleh pengumpul sampah pada waktu yang tidak ditentukan nanti. Ini juga alasan mengapa Java memakan lebih banyak memori. Faktanya, variabel di tumpukan menunjuk ke variabel di memori tumpukan. Ini adalah penunjuk di Java!
Heap Java adalah area data runtime tempat objek kelas mengalokasikan ruang. Objek ini dibuat melalui instruksi seperti new, newaray, anewarray, dan multianewarray, dan tidak memerlukan kode program untuk dirilis secara eksplisit Bertanggung jawab, keuntungan dari heap adalah dapat mengalokasikan ukuran memori secara dinamis, dan masa pakai tidak perlu diberitahukan kepada kompiler terlebih dahulu, karena secara dinamis mengalokasikan memori saat runtime, dan pengumpul sampah Java akan secara otomatis mengumpulkan ini tidak lagi digunakan data. Namun kelemahannya adalah karena kebutuhan untuk mengalokasikan memori secara dinamis saat runtime, kecepatan aksesnya lambat.
Keuntungan dari stack adalah kecepatan aksesnya lebih cepat dari heap, nomor dua setelah register, dan data stack dapat dibagikan. Namun kelemahannya adalah ukuran dan masa pakai data yang disimpan dalam tumpukan harus ditentukan dan kurangnya fleksibilitas. Tumpukan terutama menyimpan beberapa tipe dasar data variabel (int, short, long, byte, float, double, boolean, char) dan objek handle (referensi).
Fitur khusus yang sangat penting dari tumpukan adalah data yang disimpan dalam tumpukan dapat dibagikan. Misalkan kita juga mendefinisikan:
int a=3; int b=3; Kompiler pertama-tama memproses int a = 3; pertama-tama ia membuat referensi ke variabel a di tumpukan, dan kemudian memeriksa apakah ada nilai 3 di tumpukan. itu akan mengatur 3 Simpan di, lalu arahkan a ke 3. Kemudian proses int b = 3 setelah membuat variabel referensi b, karena sudah ada nilai 3 di stack, b akan langsung diarahkan ke 3. Dengan cara ini, a dan b muncul secara bersamaan, keduanya menunjuk pada kasus 3.
Saat ini, jika a=4 disetel lagi; maka kompiler akan mencari ulang apakah ada nilai 4 di tumpukan. Jika tidak, ia akan menyimpan 4 dan menunjuk ke 4; akan langsung mengarahkan a ke alamat ini. Oleh karena itu, perubahan nilai a tidak akan mempengaruhi nilai b.
Perlu diperhatikan bahwa pembagian data seperti ini berbeda dengan pembagian referensi dua objek yang menunjuk ke satu objek pada saat yang bersamaan, karena dalam hal ini modifikasi a tidak akan mempengaruhi b, melainkan diselesaikan oleh compiler, yang mana bermanfaat untuk Menghemat ruang. Jika suatu variabel referensi objek mengubah keadaan internal objek, hal itu akan mempengaruhi variabel referensi objek lainnya.