Karena Java 7 akan menggunakan pengumpulan sampah G1 baru secara default, apakah Java akan mampu menangani urutan heap yang besarnya lebih besar tanpa waktu jeda GC yang seharusnya "menghancurkan"? Adakah yang benar-benar menerapkan G1 dalam produksi, apa pengalaman Anda?
Agar adil, satu-satunya saat saya melihat jeda GC yang sangat lama berada di tumpukan yang sangat besar, jauh lebih banyak daripada yang akan dimiliki workstation. Untuk memperjelas pertanyaan saya; akankah G1 membuka gateway ke tumpukan dalam ratusan GB? TB?
java
garbage-collection
java-7
g1gc
benstpierre
sumber
sumber
Jawaban:
Sepertinya titik G1 memiliki waktu jeda yang lebih kecil, bahkan pada titik di mana ia memiliki kemampuan untuk menentukan target waktu jeda maksimum.
Pengumpulan sampah tidak hanya sekadar "Hei, sudah penuh, mari kita pindahkan semuanya sekaligus dan mulai lagi" menangani lagi - ini sangat rumit, multi-level, sistem ulir latar belakang. Itu dapat melakukan banyak pemeliharaan di latar belakang tanpa jeda sama sekali, dan itu juga menggunakan pengetahuan tentang pola yang diharapkan sistem pada waktu proses untuk membantu - seperti mengasumsikan sebagian besar objek mati tepat setelah dibuat, dll.
Saya akan mengatakan waktu jeda GC akan terus meningkat, bukan memburuk, dengan rilis di masa mendatang.
EDIT:
dalam membaca ulang, terpikir oleh saya bahwa saya menggunakan Java setiap hari - Eclipse, Azureus, dan aplikasi yang saya kembangkan, dan sudah lama sekali sejak saya melihat jeda. Bukan jeda yang signifikan, tapi maksud saya jeda sama sekali.
Saya telah melihat jeda ketika saya mengklik kanan pada windows explorer atau (kadang-kadang) ketika saya menghubungkan perangkat keras USB tertentu, tetapi dengan Java --- tidak ada sama sekali.
Apakah GC masih menjadi masalah dengan siapa pun?
sumber
Saya telah mengujinya dengan aplikasi yang berat: 60-70 GB dialokasikan ke heap, dengan 20-50 GB digunakan kapan saja. Dengan aplikasi semacam ini, sangat tidak pantas untuk mengatakan bahwa jarak tempuh Anda mungkin berbeda. Saya menjalankan JDK 1.6_22 di Linux. Versi minor itu penting-- sebelum sekitar 1.6_20, ada bug di G1 yang menyebabkan NullPointerExceptions acak.
Saya telah menemukan bahwa sangat bagus dalam menjaga target jeda yang Anda berikan sebagian besar waktu. Defaultnya tampaknya jeda 100ms (0,1 detik), dan saya telah menyuruhnya untuk melakukan setengahnya (-XX: MaxGCPauseMillis = 50). Namun, begitu memori benar-benar rendah, ia panik dan melakukan pengumpulan sampah di seluruh dunia. Dengan 65GB, itu membutuhkan waktu antara 30 detik dan 2 menit. (Jumlah CPU mungkin tidak membuat perbedaan; mungkin dibatasi oleh kecepatan bus.)
Dibandingkan dengan CMS (yang bukan GC server default, tetapi seharusnya untuk server web dan aplikasi real-time lainnya), jeda biasa jauh lebih dapat diprediksi dan dapat dibuat jauh lebih singkat. Sejauh ini saya lebih beruntung dengan CMS untuk jeda yang sangat lama, tapi itu mungkin acak; Saya melihat mereka hanya beberapa kali setiap 24 jam. Saya tidak yakin mana yang lebih cocok untuk lingkungan produksi saya saat ini, tapi mungkin G1. Jika Oracle terus menyetelnya, saya menduga G1 pada akhirnya akan menjadi pemenang yang jelas.
Jika Anda tidak mengalami masalah dengan pengumpul sampah yang ada, tidak ada alasan untuk mempertimbangkan G1 saat ini. Jika Anda menjalankan aplikasi latensi rendah, seperti aplikasi GUI, G1 mungkin adalah pilihan yang tepat, dengan MaxGCPauseMillis disetel sangat rendah. Jika Anda menjalankan aplikasi mode batch, G1 tidak akan membeli apa pun.
sumber
Meskipun saya belum menguji G1 dalam produksi, saya pikir saya akan berkomentar bahwa GC sudah bermasalah untuk kasus-kasus tanpa tumpukan yang "sangat besar". Khususnya layanan dengan, katakanlah, 2 atau 4 pertunjukan bisa sangat terpengaruh oleh GC. GC generasi muda biasanya tidak bermasalah karena mereka selesai dalam milidetik satu digit (atau paling banyak dua digit). Tetapi koleksi generasi lama jauh lebih bermasalah karena memerlukan beberapa detik dengan ukuran generasi lama 1 pertunjukan atau lebih.
Sekarang: dalam teori CMS dapat membantu banyak di sana, karena dapat menjalankan sebagian besar operasinya secara bersamaan. Namun, seiring waktu akan ada kasus di mana ia tidak dapat melakukan ini dan harus kembali ke koleksi "hentikan dunia". Dan ketika itu terjadi (setelah, katakanlah, 1 jam - tidak sering, tapi masih terlalu sering), pegang topi Anda. Ini bisa memakan waktu satu menit atau lebih. Ini khususnya bermasalah untuk layanan yang mencoba membatasi latensi maksimum; alih-alih membutuhkan, katakanlah, 25 milidetik untuk melayani permintaan, kini dibutuhkan sepuluh detik atau lebih. Untuk menambah cedera pada penghinaan, klien akan sering meminta waktu habis dan mencoba lagi, yang mengarah ke masalah lebih lanjut (alias "badai kotoran").
Ini adalah salah satu area di mana G1 diharapkan dapat banyak membantu. Saya bekerja untuk perusahaan besar yang menawarkan layanan cloud untuk penyimpanan dan pengiriman pesan; dan kami tidak dapat menggunakan CMS karena meskipun sebagian besar waktu CMS bekerja lebih baik daripada varietas paralel, CMS mengalami gangguan ini. Jadi selama sekitar satu jam semuanya menyenangkan; dan kemudian hal-hal menghantam kipas ... dan karena layanan didasarkan pada cluster, ketika satu node mendapat masalah, node lain biasanya mengikuti (karena waktu tunggu yang diinduksi GC mengarah ke node lain yang percaya node telah crash, mengarah ke perutean ulang).
Saya tidak berpikir GC adalah masalah besar bagi aplikasi, dan bahkan mungkin layanan non-cluster tidak terlalu sering terpengaruh. Tetapi semakin banyak sistem yang dikelompokkan (terutama berkat penyimpanan data NoSQL) dan ukuran heap bertambah. OldGen GC terkait secara super linier dengan ukuran heap (artinya menggandakan ukuran heap lebih dari dua kali lipat waktu GC, dengan asumsi ukuran kumpulan data langsung juga berlipat ganda).
sumber
CTO Azul, Gil Tene, memiliki gambaran bagus tentang masalah yang terkait dengan Pengumpulan Sampah dan ulasan tentang berbagai solusi dalam presentasinya Memahami Pengumpulan Sampah Jawa dan Apa yang Dapat Anda Lakukan tentangnya , dan ada detail tambahan dalam artikel ini: http: // www.infoq.com/articles/azul_gc_in_detail .
Pengumpul Sampah C4 Azul di Zing JVM kami paralel dan bersamaan, dan menggunakan mekanisme GC yang sama untuk generasi baru dan lama, bekerja secara bersamaan dan memadatkan di kedua kasus. Yang terpenting, C4 tidak memiliki stop-the-world fallback. Semua pemadatan dilakukan secara bersamaan dengan aplikasi yang berjalan. Kami memiliki pelanggan yang menjalankan sangat besar (ratusan GByte) dengan kasus waktu jeda GC yang lebih buruk <10 mdetk, dan bergantung pada aplikasi sering kali kurang dari 1-2 mdet.
Masalah dengan CMS dan G1 adalah bahwa pada titik tertentu memori heap Java harus dipadatkan, dan kedua pengumpul sampah tersebut stop-the-world / STW (yaitu menghentikan sementara aplikasi) untuk melakukan pemadatan. Jadi, meskipun CMS dan G1 dapat mengeluarkan jeda STW, mereka tidak menghilangkannya. C4 Azul, bagaimanapun, benar-benar menghilangkan jeda STW dan itulah mengapa Zing memiliki jeda GC yang rendah bahkan untuk ukuran tumpukan raksasa.
Dan untuk mengoreksi pernyataan yang dibuat dalam jawaban sebelumnya, Zing tidak memerlukan perubahan apa pun pada Sistem Operasi. Ini berjalan seperti JVM lainnya pada distro Linux yang tidak dimodifikasi.
sumber
Kami sudah menggunakan G1GC, selama hampir dua tahun. Ini berfungsi dengan baik dalam sistem pemrosesan transaksi penting misi kami, dan terbukti menjadi dukungan yang hebat dengan throughput tinggi, jeda rendah, konkurensi, dan manajemen memori berat yang dioptimalkan.
Kami menggunakan pengaturan JVM berikut:
-server -Xms512m -Xmx3076m -XX:NewRatio=50 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -XX:+AggressiveOpts -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=400 -XX:GCPauseIntervalMillis=8000 -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime
Diperbarui
-d64 -server -Xss4m -Xms1024m -Xmx4096m -XX:NewRatio=50 -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+HeapDumpOnOutOfMemoryError -XX:-DisableExplicitGC -XX:+AggressiveOpts -Xnoclassgc -XX:+UseNUMA -XX:+UseFastAccessorMethods -XX:ReservedCodeCacheSize=48m -XX:+UseStringCache -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=400 -XX:GCPauseIntervalMillis=8000
sumber
Kolektor G1 mengurangi dampak koleksi lengkap. Jika Anda memiliki aplikasi di mana Anda telah mengurangi kebutuhan untuk koleksi lengkap, pengumpul Sapu peta Bersamaan sama baiknya dan menurut pengalaman saya memiliki waktu pengumpulan kecil yang lebih singkat.
sumber
Sepertinya G1 yang memulai JDK7u4 akhirnya didukung secara resmi, lihat RN untuk JDK7u4 http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html .
Dari pengujian kami masih untuk JVM besar yang disetel CMS masih bertindak lebih baik daripada G1 tapi saya rasa itu akan tumbuh lebih baik.
sumber
Baru-baru ini saya telah dipindahkan dari
CMS ke G1GC dengan prosesor heap 4G & 8 inti di server dengan JDK 1.7.45 .
(JDK 1.8.x G1GC lebih disukai daripada 1.7 tetapi karena beberapa batasan, saya harus tetap menggunakan versi 1.7.45)
Saya telah mengonfigurasi di bawah parameter kunci dan menyimpan semua parameter lainnya ke nilai default.
Jika Anda ingin menyempurnakan parameter ini, lihat artikel oracle ini.
Pengamatan kunci:
Tapi tetap saya senang bahwa waktu jeda Max GC kurang dari pada CMS. Saya telah menyetel waktu jeda Max GC sebagai 1,5 detik dan nilai ini belum terlampaui.
Pertanyaan SE terkait:
Pengumpulan dan dokumentasi sampah Java 7 (JDK 7) di G1
sumber
CMS dapat menyebabkan kinerja yang menurun secara perlahan meskipun Anda menjalankannya tanpa mengumpulkan objek bertenor. Ini karena fragmentasi memori yang seharusnya dihindari oleh G1.
Mitos tentang G1 yang hanya tersedia dengan dukungan berbayar hanyalah mitos. Sun dan sekarang Oracle telah mengklarifikasi hal ini di halaman JDK.
sumber
G1 GC seharusnya bekerja lebih baik. Namun jika menyetel -XX: MaxGCPauseMill terlalu agresif, sampah akan terkumpul terlalu lambat. Dan itulah mengapa GC penuh dipicu dalam contoh David Leppik.
sumber
Saya baru saja menerapkan G1 Garbage Collector di proyek Terracotta Big Memory kami. Saat mengerjakan berbagai jenis kolektor, G1 memberi kami hasil terbaik dengan waktu respons kurang dari 600ms.
Anda dapat menemukan hasil tes (total 26) di sini
Semoga membantu.
sumber
Saya baru-baru ini memigrasikan bagian dari Twicsy ke server baru dengan RAM 128GB dan memutuskan untuk menggunakan 1.7. Saya mulai menggunakan semua pengaturan memori yang sama seperti yang saya gunakan dengan 1.6 (Saya memiliki beberapa contoh yang menjalankan berbagai hal, mulai dari tumpukan 500mb hingga 15GB, dan sekarang yang baru dengan 40GB) dan itu tidak berjalan dengan baik sama sekali . 1.7 tampaknya menggunakan lebih banyak heap daripada 1.6, dan saya mengalami banyak masalah selama beberapa hari pertama. Untungnya, saya memiliki banyak RAM untuk digunakan dan meningkatkan RAM untuk sebagian besar proses saya, tetapi masih mengalami beberapa masalah. MO normal saya adalah menggunakan ukuran heap minimum yang sangat kecil yaitu 16m, bahkan dengan heap maksimum beberapa gigabyte, lalu aktifkan GC tambahan. Ini meminimalkan jeda. Namun itu tidak berfungsi sekarang, dan saya harus meningkatkan ukuran minimum menjadi tentang apa yang saya harapkan untuk digunakan rata-rata di heap, dan itu berhasil dengan sangat baik. Saya masih mengaktifkan GC tambahan, tetapi saya akan mencobanya tanpa. Tidak ada jeda apa pun sekarang, dan segala sesuatunya tampak berjalan sangat cepat. Jadi, menurut saya pesan moral dari cerita ini adalah jangan berharap pengaturan memori Anda diterjemahkan dengan sempurna dari 1.6 ke 1.7.
sumber
G1 membuat aplikasi jauh lebih gesit: kemunduran aplikasi akan meningkat - aplikasi dapat dinamai "soft-real-time". Ini dilakukan dengan mengganti dua jenis rangkaian GC (yang kecil kecil dan yang besar pada Gen Bertenur) menjadi yang berukuran sama kecil.
Untuk lebih jelasnya lihat ini: http://geekroom.de/java/java-expertise-g1-fur-java-7/
sumber
Saya bekerja dengan Java, untuk Heap kecil dan besar, dan pertanyaan tentang GC dan GC Penuh muncul setiap hari, karena batasannya mungkin lebih ketat daripada yang lain: di lingkungan tertentu, 0,1 detik dari GC pemulung atau GC Penuh, matikan hanya analisis fonction, dan memiliki konfigurasi yang sangat baik dan kapabilitas yang penting (CMS, iCMS, lainnya ... target ada di sini untuk mendapatkan waktu respons terbaik dengan perlakuan hampir waktu nyata (di sini perlakuan waktu nyata sering kali 25 md) , jadi, pada dasarnya, setiap peningkatan dalam ergonomi dan heuristik GC dipersilakan!
sumber
Saya menggunakan G1GC di Java 8 dan juga dengan Groovy (juga Java 8), dan saya melakukan berbagai jenis beban kerja, dan secara umum G1GC bekerja seperti ini:
Penggunaan memori sangat rendah, misalnya 100MB, bukan 500MB dibandingkan dengan pengaturan Java default
Waktu responsnya konsisten dan sangat rendah
Kinerja antara pengaturan default dan G1GC adalah 20% perlambatan saat menggunakan G1GC dalam skenario kasus terburuk (tanpa tuning, aplikasi single-threaded). Ini tidak banyak mempertimbangkan waktu respons yang baik dan penggunaan memori yang rendah.
Saat dijalankan dari Tomcat yang multi-threaded, performa keseluruhan 30% lebih baik dan penggunaan memori jauh lebih rendah serta waktu respons yang jauh lebih rendah.
Jadi secara keseluruhan, saat menggunakan beban kerja yang sangat beragam, G1GC adalah kolektor yang sangat baik untuk Java 8 untuk aplikasi multi-thread, dan bahkan untuk single-threaded ada beberapa keuntungan.
sumber
Tidak disarankan untuk menggunakan java8 w / G1GC untuk penghitungan titik mengambang dengan JVM seperti hotspot. Berbahaya untuk integritas & akurasi aplikasi.
https://bugs.openjdk.java.net/browse/JDK-8148175
JDK-8165766
JDK-8186112
sumber