Menjelajahi JVM Tuning Flags

1. Ikhtisar

Anda dapat menyetel HotSpot JVM dengan berbagai bendera penyetelan. Karena ada ratusan flag seperti itu, melacaknya dan nilai defaultnya bisa sedikit menakutkan.

Dalam tutorial ini, kami akan memperkenalkan beberapa cara untuk menemukan flag penyetelan seperti itu dan mempelajari cara bekerja dengannya.

2. Sekilas tentang Opsi Java

The java perintah mendukung berbagai macam bendera jatuh ke dalam kategori berikut:

  • Opsi standar yang dijamin akan didukung oleh semua implementasi JVM di luar sana. Biasanya, opsi ini digunakan untuk tindakan sehari-hari seperti –classpath, -cp, –version, dan seterusnya
  • Opsi tambahan yang tidak didukung oleh semua implementasi JVM dan biasanya dapat berubah. Opsi ini dimulai dengan -X

Harap dicatat bahwa kami tidak boleh menggunakan opsi tambahan ini dengan santai. Selain itu, beberapa opsi tambahan tersebut lebih maju dan dimulai dengan -XX .

Sepanjang artikel ini, kita akan fokus pada flag -XX tingkat lanjut .

3. Bendera Tuning JVM

Untuk mencantumkan flag tuning JVM global, kita dapat mengaktifkan flag PrintFlagsFinal sebagai berikut:

>> java -XX:+PrintFlagsFinal -version [Global flags] uintx CodeCacheExpansionSize = 65536 {pd product} {default} bool CompactStrings = true {pd product} {default} bool DoEscapeAnalysis = true {C2 product} {default} double G1ConcMarkStepDurationMillis = 10.000000 {product} {default} size_t G1HeapRegionSize = 1048576 {product} {ergonomic} uintx MaxHeapFreeRatio = 70 {manageable} {default} // truncated openjdk version "14" 2020-03-17 OpenJDK Runtime Environment (build 14+36-1461) OpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)

Seperti yang ditunjukkan di atas, beberapa tanda memiliki nilai default untuk versi JVM khusus ini.

Nilai default untuk beberapa bendera mungkin berbeda pada platform yang berbeda, yang ditunjukkan di kolom terakhir. Misalnya, produk berarti bahwa pengaturan default dari bendera tersebut seragam di semua platform; yang produk pd berarti bahwa pengaturan default dari bendera adalah tergantung platform. The dikelola nilai dapat berubah secara dinamis pada saat runtime.

3.1. Bendera Diagnostik

The PrintFlagsFinal bendera, bagaimanapun, tidak menunjukkan semua bendera tala mungkin. Misalnya, untuk juga melihat tanda penyetelan diagnostik, kita harus menambahkan tanda UnlockDiagnosticVMOptions :

>> java -XX:+PrintFlagsFinal -version | wc -l 557 >> java -XX:+PrintFlagsFinal -XX:+UnlockDiagnosticVMOptions -version | wc -l 728

Jelas, ada beberapa ratus panji lagi saat kami menyertakan opsi diagnostik. Misalnya, mencetak statistik pelacakan memori asli hanya tersedia sebagai bagian dari tanda diagnostik:

bool PrintNMTStatistics = false {diagnostic} {default}

3.2. Bendera Eksperimental

Untuk juga melihat opsi eksperimental, kita harus menambahkan tanda UnlockExperimentalVMOptions :

>> java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version | wc -l 809

3.3. Bendera JVMCI

Pada Java 9, antarmuka kompilator JVM atau JVMCI memungkinkan kita menggunakan kompilator yang ditulis dalam Java, seperti Graal, sebagai kompilator dinamis.

Untuk melihat opsi yang terkait dengan JVMCI, kita harus menambahkan beberapa bendera lagi dan bahkan mengaktifkan JVMCI:

>> java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions \ >> -XX:+JVMCIPrintProperties -XX:+EnableJVMCI -XX:+PrintFlagsFinal -version | wc -l 1516

Namun, sebagian besar waktu, menggunakan opsi global, diagnostik, dan eksperimental sudah cukup dan akan membantu kita menemukan bendera yang ada dalam pikiran kita.

3.4. Menyatukan Semuanya

Kombinasi opsi ini dapat membantu kami menemukan bendera penyetelan, terutama saat kami tidak ingat nama persisnya. Misalnya, untuk menemukan bendera penyetelan yang terkait dengan referensi lunak di Java:

>> alias jflags="java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version" >> jflags | grep Soft size_t SoftMaxHeapSize = 4294967296 {manageable} {ergonomic} intx SoftRefLRUPolicyMSPerMB = 1000 {product} {default}

Dari hasil tersebut, kita dapat dengan mudah menebak bahwa SoftRefLRUPolicyMSPerMB adalah flag yang kita cari.

4. Berbagai Jenis Bendera

Di bagian sebelumnya, kami mengabaikan subjek penting: jenis bendera. Mari kita lihat lagi keluaran java -XX: + PrintFlagsFinal -version :

[Global flags] uintx CodeCacheExpansionSize = 65536 {pd product} {default} bool CompactStrings = true {pd product} {default} bool DoEscapeAnalysis = true {C2 product} {default} double G1ConcMarkStepDurationMillis = 10.000000 {product} {default} size_t G1HeapRegionSize = 1048576 {product} {ergonomic} uintx MaxHeapFreeRatio = 70 {manageable} {default} // truncated

Seperti yang ditunjukkan di atas, setiap bendera memiliki tipe tertentu.

Opsi Boolean digunakan untuk mengaktifkan atau menonaktifkan fitur . Opsi semacam itu tidak membutuhkan nilai. Untuk mengaktifkannya, kita hanya perlu memberi tanda plus sebelum nama opsi:

-XX:+PrintFlagsFinal

Sebaliknya, untuk menonaktifkannya, kita harus menambahkan tanda minus sebelum namanya:

-XX:-RestrictContended

Jenis bendera lainnya membutuhkan nilai argumen. Dimungkinkan untuk memisahkan nilai dari nama opsi dengan spasi, titik dua, tanda sama dengan, atau argumen dapat langsung mengikuti nama opsi (sintaks yang tepat berbeda untuk setiap opsi):

-XX:ObjectAlignmentInBytes=16 -Xms5g -Xlog:gc

5. Dokumentasi dan Kode Sumber

Menemukan nama bendera yang tepat adalah satu hal. Menemukan apa yang dilakukan oleh bendera tertentu di bawah tenda adalah cerita lain.

Salah satu cara untuk mengetahui detail semacam ini adalah dengan melihat dokumentasinya. Misalnya, dokumentasi untuk perintah java di bagian spesifikasi alat JDK adalah tempat yang tepat untuk memulai.

Terkadang, tidak ada dokumentasi yang dapat mengalahkan kode sumbernya. Oleh karena itu, jika kita memiliki nama dari sebuah flag tertentu, maka kita dapat menjelajahi kode sumber JVM untuk mengetahui apa yang terjadi.

Misalnya, kita dapat memeriksa kode sumber JVM HotSpot dari GitHub atau bahkan repositori Mercurial mereka dan kemudian:

>> git clone [email protected]:openjdk/jdk14u.git openjdk >> cd openjdk/src/hotspot >> grep -FR 'PrintFlagsFinal' . ./share/runtime/globals.hpp: product(bool, PrintFlagsFinal, false, ./share/runtime/init.cpp: if (PrintFlagsFinal || PrintFlagsRanges) {

Di sini kami mencari semua file yang berisi string PrintFlagsFinal . Setelah menemukan file yang bertanggung jawab, kita dapat melihat sekeliling dan melihat bagaimana flag spesifik itu bekerja.

6. Kesimpulan

Pada artikel ini, kami melihat bagaimana kami dapat menemukan hampir semua bendera penyetelan JVM yang tersedia dan juga mempelajari beberapa trik untuk bekerja dengannya secara lebih efektif.