Berbagi teknologi

terkait JVM

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Arsitektur JDK

Fitur lintas platform bahasa Java

Struktur keseluruhan JVM dan model memori

Pengaturan parameter memori JVM

Format pengaturan parameter JVM dari program Spring Boot (startup Tomcat langsung ditambahkan ke file catalina.sh di direktori bin):

java -Xms2048M -Xmx2048M -Xmn1024M -Xss512K -XX:UkuranMetaspace=256M -XX:UkuranMetaspaceMaks=256M -jar microservice-eureka-server.jar

Kesimpulannya:

Semakin kecil pengaturan -Xss, semakin kecil nilai hitungannya, yang berarti lebih sedikit frame tumpukan yang dapat dialokasikan dalam tumpukan thread, namun jumlah thread yang dapat dibuka akan lebih banyak untuk JVM secara keseluruhan.

-Xss: ukuran tumpukan setiap utas, default 1M

-Xms: Mengatur ukuran heap awal yang tersedia, defaultnya adalah 1/64 memori fisik

-Xmx: Mengatur ukuran heap maksimum yang tersedia, defaultnya adalah 1/4 dari memori fisik

-Xmn: ukuran generasi baru

-XX:NewRatio: Default 2 berarti generasi baru menyumbang 1/2 dari generasi lama dan 1/3 dari seluruh memori heap.

-XX:SurvivorRatio: Default 8 berarti area yang selamat menempati 1/8 memori Eden, yaitu 1/10 memori generasi baru.

Ada dua parameter JVM tentang metaspace: -XX:MetaspaceSize=N dan -XX:MaxMetaspaceSize=N

-XX: MaxMetaspaceSize: Mengatur ukuran metaspace maksimum. Defaultnya adalah -1, artinya tidak ada batasan, atau hanya dibatasi oleh ukuran memori lokal.

-XX: MetaspaceSize: Menentukan ambang batas awal metaspace untuk memicu Fullgc (tidak ada ukuran awal tetap untuk metaspace), dalam byte. Defaultnya adalah sekitar 21M. Ketika nilai ini tercapai, gc penuh akan dipicu untuk pembongkaran tipe, dan kolektor akan Menyesuaikan nilai ini: Jika sejumlah besar ruang dibebaskan, kurangi nilainya dengan tepat; jika sejumlah kecil ruang dibebaskan, tambah nilainya tanpa melebihi -XX:MaxMetaspaceSize (jika disetel). Ini memiliki arti yang berbeda dari parameter -XX:PermSize di versi jdk sebelumnya. -XX:PermSize mewakili kapasitas awal generasi permanen.

Karena mengubah ukuran metaspace memerlukan GC Penuh, ini adalah operasi yang sangat mahal. Jika sejumlah besar GC Penuh terjadi saat aplikasi dimulai, hal ini biasanya disebabkan oleh pengubahan ukuran generasi permanen atau metaspace direkomendasikan untuk Dalam parameter JVM, atur MetaspaceSize dan MaxMetaspaceSize ke nilai yang sama, dan atur lebih besar dari nilai awal. Untuk mesin dengan memori fisik 8G, saya biasanya menetapkan kedua nilai ke 256M.

Penciptaan objek

Tajuk objek

Di mesin virtual HotSpot, tata letak objek yang disimpan dalam memori dapat dibagi menjadi tiga area: header objek (Header), data instan (Instance Data) dan padding penyelarasan (Padding). Header objek mesin virtual HotSpot mencakup dua bagian informasi. Bagian pertama digunakan untuk menyimpan data runtime dari objek itu sendiri, seperti kode hash (HashCode), usia pembuatan GC, tanda status kunci, kunci yang dipegang oleh thread. , ID thread yang bias, stempel waktu Favorit, dll. Bagian lain dari header objek adalah penunjuk tipe, yang merupakan penunjuk objek ke metadata kelasnya. Mesin virtual menggunakan penunjuk ini untuk menentukan di kelas mana objek tersebut berasal.

Tajuk objek 32-bit

Tajuk objek 64-bit

kompresi penunjuk

1. Menggunakan pointer 32-bit (penyimpanan sebenarnya menggunakan 64-bit) di HotSpot pada platform 64-bit akan menggunakan memori sekitar 1,5 kali lebih banyak. Menggunakan pointer yang lebih besar untuk memindahkan data antara memori utama dan cache membutuhkan lebih banyak bandwidth waktu, GC juga akan berada di bawah tekanan yang lebih besar

2. Untuk mengurangi konsumsi memori pada platform 64-bit, aktifkan fungsi kompresi penunjuk

3. Di jvm, alamat 32-bit mendukung hingga memori 4G (2 pangkat 32), yang dapat dioptimalkan dengan mengompresi dan menyandikan penunjuk objek saat disimpan di memori heap, dan kemudian mendekodekannya setelah mengambilnya keluar ke register cpu (penunjuk objek ada di heap Ini adalah 32 bit, 35 bit di register, 2 pangkat 35 = 32G), memungkinkan jvm untuk mendukung konfigurasi memori yang lebih besar (kurang dari atau sama dengan 32G) menggunakan hanya alamat 32-bit

4. Ketika memori heap kurang dari 4G, tidak perlu mengaktifkan kompresi pointer. JVM akan langsung menghapus alamat 32-bit yang tinggi, yaitu menggunakan ruang alamat virtual yang rendah.

5. Ketika memori heap lebih besar dari 32G, penunjuk kompresi akan menjadi tidak valid dan 64-bit (yaitu 8 byte) akan dipaksa untuk mengalamatkan objek Java. Hal ini akan menyebabkan masalah 1, jadi lebih baik tidak memilikinya memori tumpukan lebih besar dari 32G.

Analisis escape dan penggantian judul alokasi pada tumpukan objek

Dalam hal ini, JVM dapat mengoptimalkan lokasi alokasi memori objek dengan mengaktifkan parameter analisis escape (-XX:+DoEscapeAnalysis), sehingga dialokasikan pada stack terlebih dahulu melalui penggantian skalar (alokasi pada stack). analisis diaktifkan secara default setelah JDK7. Jika Anda ingin Matikan menggunakan parameter (-XX:-DoEscapeAnalysis)

Penggantian skalar: Ketika ditentukan melalui analisis escape bahwa objek tidak akan diakses secara eksternal dan objek dapat didekomposisi lebih lanjut, JVM tidak akan membuat objek, tetapi akan menguraikan variabel anggota objek menjadi beberapa variabel anggota yang digunakan dengan metode ini dan menggantinya. Variabel anggota alternatif ini mengalokasikan ruang pada bingkai tumpukan atau register, sehingga tidak ada alokasi memori yang tidak mencukupi untuk objek karena tidak ada ruang bersebelahan yang besar. Aktifkan parameter penggantian skalar (-XX:+EliminateAllocations), yang diaktifkan secara default setelah JDK7.

Besaran skalar dan agregat: Skalar adalah besaran yang tidak dapat diuraikan lebih lanjut, dan tipe data dasar JAVA adalah skalar (seperti int, long dan tipe data dasar serta tipe referensi lainnya, dll.). adalah besaran yang dapat diuraikan lebih lanjut, dan Jumlah ini disebut jumlah polimerisasi. Di JAVA, objek adalah agregat yang dapat didekomposisi lebih lanjut.

Benda-benda besar langsung masuk ke generasi lama

Objek besar adalah objek yang memerlukan ruang memori kontinu dalam jumlah besar (seperti string dan array). Parameter JVM -XX:PretenureSizeThreshold dapat mengatur ukuran objek yang besar. Jika objek melebihi ukuran yang ditetapkan, maka akan langsung masuk ke generasi lama dan tidak akan masuk ke generasi muda.

Misalnya, atur parameter JVM: -XX:PretenureSizeThreshold=1000000 (unit adalah byte) -XX:+UseSerialGC. Jika Anda menjalankan program pertama di atas, Anda akan menemukan bahwa objek besar langsung masuk ke generasi lama.

Kenapa harus seperti ini?

Untuk menghindari operasi penyalinan saat mengalokasikan memori untuk objek besar dan mengurangi efisiensi.

Penilaian usia dinamis objek

Di area Survivor tempat objek ditempatkan saat ini (salah satu area, area s tempat objek ditempatkan), ukuran total sekumpulan objek lebih besar dari 50% ukuran memori area Survivor ini (-XX :TargetSurvivorRatio dapat ditentukan), maka saat ini lebih besar dari Objek yang sama dengan usia maksimum kumpulan objek ini dapat langsung memasuki usia tua jumlah beberapa objek usia dengan usia 1 + usia 2 + usia n melebihi 50% dari area Survivor. Saat ini, semua objek dengan usia n (inklusif) ke atas akan dimasukkan ke dalam generasi lama. Aturan ini sebenarnya berharap agar benda-benda yang mampu bertahan lama akan segera memasuki usia tua. Mekanisme penilaian usia objek dinamis umumnya dipicu setelah gc kecil.

Mekanisme jaminan alokasi ruang generasi lama

Sebelum setiap minor gc di generasi muda, JVM akan menghitung sisa ruang kosong di generasi lama.

Jika ruang yang tersedia kurang dari jumlah seluruh benda yang ada pada generasi muda (termasuk benda sampah)

Ini akan memeriksa apakah parameter "-XX:-HandlePromotionFailure" (ditetapkan secara default di jdk1.8) disetel.

Jika parameter ini ada, parameter ini akan memeriksa apakah ukuran memori yang tersedia di generasi lama lebih besar dari ukuran rata-rata objek yang masuk ke generasi lama setelah setiap gc minor sebelumnya.

Jika hasil dari langkah sebelumnya kurang dari atau parameter yang disebutkan sebelumnya tidak disetel, maka gc Penuh akan terpicu, dan generasi lama dan generasi muda akan dikumpulkan bersama Jika masih belum cukup ruang untuk menyimpan yang baru benda setelah didaur ulang, "OOM" akan terjadi.

Tentu saja, jika ukuran sisa objek yang masih hidup yang perlu dipindahkan ke generasi lama setelah gc minor masih lebih besar dari ruang yang tersedia di generasi lama, gc penuh juga akan terpicu setelah gc penuh, jika ada masih tidak ada ruang untuk objek yang bertahan setelah gc minor, "OOM" juga akan terjadi

Algoritma analisis keterjangkauan

Menganalisis mekanisme pemuatan kelas JVM dari tingkat kode sumber JDK

Proses pemuatan kelas

Pemuat kelas dan mekanisme delegasi orang tua

Mengapa merancang delegasi orang tua?

Penjelasan mendetail tentang pemuat khusus Tomcat

Beberapa pemuat kelas utama kucing jantan:

commonLoader: Pemuat kelas Tomcat yang paling dasar. Kelas di jalur pemuatan dapat diakses oleh wadah Tomcat itu sendiri dan setiap aplikasi Web;

catalinaLoader: Pemuat kelas privat dari wadah Tomcat. Kelas-kelas di jalur pemuatan tidak terlihat oleh Webapp;

sharedLoader: Pemuat kelas yang dibagikan oleh masing-masing aplikasi Web. Kelas-kelas di jalur pemuatan dapat dilihat oleh semua aplikasi Web, namun tidak dapat dilihat oleh kontainer Tomcat;

WebappClassLoader: Setiap pemuat kelas privat Webapp. Kelas-kelas di jalur pemuatan hanya terlihat oleh Webapp saat ini, seperti memuat kelas terkait dalam paket perang. Setiap aplikasi paket perang memiliki WebappClassLoader sendiri untuk mencapai isolasi timbal balik, seperti paket perang yang berbeda aplikasi. Versi pegas yang berbeda diperkenalkan sehingga implementasi dapat memuat versi pegasnya masing-masing;

model memori

Algoritma pengumpulan sampah

pemulung

Implementasi algoritma yang mendasari pengumpulan sampah