Untuk mengonfigurasi parameter JVM untuk meminimalkan pengumpulan sampah (GC) jeda, penting untuk memahami operasi mendasar dari berbagai kolektor sampah dan mekanisme tuning yang tersedia di JVM. Proses konfigurasi melibatkan pemilihan algoritma pengumpulan sampah yang sesuai, ukuran tuning heap, mengkonfigurasi tujuan waktu jeda, parameter threading, dan mengoptimalkan daerah memori. Di bawah ini adalah sintesis terperinci dari tuning JVM untuk meminimalkan jeda GC berdasarkan sumber otoritatif dan praktik terbaik:
Memilih pengumpul sampah yang tepat
JVM menawarkan beberapa algoritma pengumpulan sampah, masing -masing dengan karakteristik yang berbeda mengenai throughput, waktu jeda, dan penggunaan sumber daya:
- Serial GC: Menggunakan satu utas untuk GC. Ini menghentikan semua utas aplikasi selama pengumpulan, menghasilkan jeda panjang. Ini umumnya tidak cocok untuk meminimalkan jeda dalam aplikasi yang lebih besar.
- Paralel GC: Menggunakan beberapa utas untuk melakukan pengumpulan sampah, mengurangi waktu jeda dibandingkan dengan serial GC dengan memanfaatkan beberapa inti CPU. Ini berorientasi throughput tetapi masih berhenti jeda utas aplikasi selama GC.
- Concurrent Mark-Sweep (CMS) GC: Melakukan banyak pekerjaan pengumpulan sampah secara bersamaan dengan aplikasi, secara signifikan mengurangi waktu jeda dengan hanya menjeda secara singkat aplikasi pada fase GC tertentu. Ini cocok untuk aplikasi latensi rendah.
- Sampah pertama (G1) GC: Membagi tumpukan menjadi daerah dan berfokus pada pengumpulan daerah dengan sampah terbanyak terlebih dahulu. Ini bertujuan untuk memberikan waktu jeda yang dapat diprediksi dan throughput yang baik dengan mencampur fase bersamaan dan paralel. Seringkali default dalam versi JVM modern.
- Shenandoah dan ZGC: Kolektor latensi rendah ini melakukan semua atau sebagian besar GC bekerja secara bersamaan, bertujuan untuk jeda yang sangat pendek atau hampir tidak terlihat, cocok untuk tumpukan besar dan aplikasi yang sangat responsif.
Memilih kolektor yang tepat tergantung pada persyaratan aplikasi seperti waktu jeda yang ditoleransi maksimum, ukuran tumpukan, dan karakteristik beban kerja.
Konfigurasi ukuran ukuran ###
Ukuran tumpukan memiliki dampak langsung pada frekuensi GC dan jeda durasi:
-Tetapkan ukuran heap awal dan maksimum sama: menggunakan `-xms` dan` -xmx` dengan nilai yang sama menghindari pengubah ukuran banyak, yang dapat memperkenalkan jeda selama runtime.
- Ukuran tumpukan yang memadai: Tumpukan yang kurang besar menyebabkan koleksi yang sering terjadi, meningkatkan jeda. Namun, over-alocating mengarah ke siklus GC yang lebih lama. Find a balance based on application memory needs.
- Pantau log GC dan metrik penggunaan tumpukan untuk menyetel ukuran tumpukan dengan tepat.
Mengontrol waktu jeda GC
JVM menyediakan parameter untuk menetapkan tujuan untuk waktu jeda GC maksimum:
- `-xx: maxgcpausemillis =`: menetapkan waktu jeda maksimum target dalam milidetik untuk kolektor untuk mencoba bertemu. Meskipun tidak dijamin, JVM berupaya menyesuaikan throughput dan pekerjaan GC untuk menghindari melebihi waktu jeda ini.
- Gunakan parameter ini dengan G1 GC atau kolektor lain yang mendukung tujuan waktu jeda untuk memandu JVM dalam menyeimbangkan throughput dan latensi.
Threading dan paralelisme
Memanfaatkan banyak utas selama pengumpulan sampah mengurangi durasi jeda:
- `-xx: paralelgcthreads =`: Mengatur jumlah utas yang digunakan selama fase paralel GC. Lebih banyak utas dapat mengurangi waktu jeda tetapi juga dapat meningkatkan penggunaan CPU.
- `-xx: concgcthreads =`: Untuk kolektor bersamaan seperti CMS dan G1, menetapkan jumlah utas yang melakukan fase bersamaan.
- Jumlah utas yang optimal harus selaras dengan jumlah inti CPU yang tersedia dan beban kerja; Utas yang berlebihan dapat menurunkan kinerja.
Menyetel ukuran generasi muda dan tua
Tumpukan biasanya dibagi menjadi beberapa generasi muda dan tua. Menyetel ukuran mereka mempengaruhi perilaku GC:
- Ukuran generasi muda: Generasi muda yang lebih besar mengurangi frekuensi GC kecil tetapi meningkatkan waktu jeda kecil GC. Sesuaikan berdasarkan tingkat alokasi objek.
- Ukuran Generasi Lama: Mempengaruhi seberapa sering GC utama/penuh berjalan dan durasinya.
- G1 GC membagi tumpukan menjadi banyak daerah berukuran sama dan mengelola ukuran secara dinamis tetapi memungkinkan ambang inisiasi tuning dengan parameter seperti `-xx: InitiatingHeapOccupancyPercent`.
parameter spesifik pengumpul sampah
Untuk G1 GC, biasanya digunakan dalam JVM modern:
- `-xx:+useg1gc`: Mengaktifkan G1 GC.
- `-xx: maxgcpausemillis =`: jeda target waktu.
- `-xx: InitiatingHeapOccupancyPent =`: Memulai tanda bersamaan ketika tumpukan mencapai hunian ini.
- `-xx:+Usestringdedupplication`: Mengurangi jejak memori dengan deduplikasi string.
- Hindari secara eksplisit menetapkan ukuran generasi muda, karena dapat mengganggu tujuan waktu jeda G1.
Untuk CMS GC:
- `-xx:+useconcmarksweepgc`: memungkinkan cms.
-Tuning fokus pada mengurangi penghentian stop-the-world global dengan menyesuaikan ambang inisiasi dan jumlah benang.
Untuk GC paralel (berorientasi throughput):
-`-xx:+useparallelgc` dan` -xx:+useparalleloldgc`: Mengaktifkan GC paralel untuk generasi muda dan tua.
- Tune jumlah utas GC dengan `-xx: parallelgcthreads`.
Mengurangi tingkat alokasi objek
Mengurangi laju di mana objek baru dibuat mengurangi tekanan GC:
- Profil dan optimalkan kode untuk meminimalkan pembuatan objek yang tidak perlu.
- Gunakan pengumpulan dan penggunaan kembali objek jika memungkinkan.
- Sesuaikan parameter JVM untuk mengatur daerah memori internal untuk pola alokasi objek yang lebih baik.
Hindari panggilan GC eksplisit
- Nonaktifkan panggilan GC eksplisit dari kode aplikasi atau alat eksternal yang dapat memicu jeda GC penuh menggunakan `-xx:+disablexplicitgc`.
Pemantauan dan Penebangan
Untuk memahami dan menyetel perilaku GC, aktifkan logging GC terperinci:
- Gunakan `-xlog: GC*` dalam JVM mendukung logging terpadu (Java 9+).
-Dalam JVM yang lebih lama, gunakan `-xx:+printgcdetails -xx:+printgcdatestamps -xloggc:`.
Menganalisis log untuk mengidentifikasi penyebab jeda dan menyetelnya.
Rekomendasi Umum
- Mulailah menyetel dengan batu tulis yang bersih dengan menghapus argumen JVM yang sudah ketinggalan zaman.
- Uji perubahan dalam lingkungan seperti produksi.
- Gunakan alat seperti Java Flight Recorder, VisualVM, atau profiler komersial untuk mengumpulkan data penggunaan GC dan memori.
- Iterasi langkah penyetelan berdasarkan waktu jeda GC yang diamati, throughput, dan responsif aplikasi.
Singkatnya, meminimalkan jvm pengumpulan sampah jeda melibatkan pemilihan pengumpul sampah yang sesuai (lebih disukai G1, ZGC, atau Shenandoah untuk persyaratan jeda rendah), ukuran dan generasi ukuran yang tepat, menetapkan tujuan waktu jeda, penyetelan utas konkurensi, meminimalkan laju alokasi objek, melumpuhkan GC eksplisit, dan pemantauan yang cermat. Spesifik akan tergantung pada beban kerja aplikasi, ukuran tumpukan, versi JVM, dan karakteristik perangkat keras. Penyesuaian harus dilakukan secara bertahap dan divalidasi dengan alat pemantauan dan log GC terperinci untuk mencapai keseimbangan waktu throughput dan jeda yang diinginkan.
Pendekatan ini memastikan bahwa pengumpulan sampah JVM beroperasi secara efisien dengan gangguan minimal terhadap kinerja aplikasi.