Pesan-pesan Log Pengumpulan Sampah Jawa

96

Saya telah mengkonfigurasi java untuk membuang informasi pengumpulan sampah ke dalam log ( GC verbose ). Saya tidak yakin apa arti entri pengumpulan sampah di log. Contoh entri ini diposting di bawah ini. Saya telah mencari-cari di Google dan belum menemukan penjelasan yang solid.

Saya memiliki beberapa tebakan yang masuk akal, tetapi saya sedang mencari jawaban yang memberikan definisi yang ketat tentang arti angka-angka dalam entri, didukung oleh sumber yang dapat dipercaya. +1 otomatis untuk semua jawaban yang mengutip dokumentasi matahari. Pertanyaan saya adalah:

  1. Apa yang dimaksud dengan PSYoungGen? Saya berasumsi itu ada hubungannya dengan generasi sebelumnya (lebih muda?), Tapi apa sebenarnya?
  2. Apa perbedaan antara triplet angka kedua dan yang pertama?
  3. Mengapa nama (PSYoungGen) ditentukan untuk triplet pertama angka tetapi tidak yang kedua?
  4. Apa arti setiap angka (ukuran memori) dalam triplet. Misalnya di 109884K-> 14201K (139904K), adalah memori sebelum GC 109884k dan kemudian dikurangi menjadi 14201K. Bagaimana angka ketiga relevan? Mengapa kita membutuhkan rangkaian angka kedua?

8109.128: [GC [PSYoungGen: 109884K-> 14201K (139904K)] 691015K-> 595332K (1119040K), 0,0454530 dtk]

8112.111: [GC [PSYoungGen: 126649K-> 15528K (142336K)] 707780K-> 605892K (1121472K), 0,0934560 dtk]

8112.802: [GC [PSYoungGen: 130344K-> 3732K (118592K)] 720708K-> 607895K (1097728K), 0,0682690 dtk]

Ethan Heilman
sumber
seluruh tumpukan, generasi muda bagian dari heap, gc minor untuk cara kerja gc, periksa misalnya cubrid.org/blog/dev-platform/…
MarianP

Jawaban:

90

Sebagian besar dijelaskan dalam Panduan Tuning GC (yang sebaiknya Anda baca juga).

Opsi baris perintah -verbose:gcmenyebabkan informasi tentang heap dan pengumpulan sampah dicetak di setiap koleksi. Misalnya, berikut adalah keluaran dari aplikasi server besar:

[GC 325407K->83000K(776768K), 0.2300771 secs]
[GC 325816K->83372K(776768K), 0.2454258 secs]
[Full GC 267628K->83769K(776768K), 1.8479984 secs]

Di sini kita melihat dua koleksi minor diikuti oleh satu koleksi mayor. Angka sebelum dan sesudah panah (misalnya, 325407K->83000Kdari baris pertama) masing-masing menunjukkan ukuran gabungan dari objek aktif sebelum dan sesudah pengumpulan sampah. Setelah koleksi kecil, ukurannya mencakup beberapa objek yang sampah (tidak lagi hidup) tetapi tidak dapat diklaim kembali. Objek-objek ini baik yang terkandung dalam generasi bertenor, atau dirujuk dari generasi tetap atau permanen.

Angka berikutnya dalam tanda kurung (misalnya, (776768K)lagi dari baris pertama) adalah ukuran heap yang dikomitmenkan: jumlah ruang yang dapat digunakan untuk objek java tanpa meminta lebih banyak memori dari sistem operasi. Perhatikan bahwa nomor ini tidak termasuk salah satu ruang yang selamat, karena hanya satu yang dapat digunakan pada waktu tertentu, dan juga tidak termasuk pembuatan permanen, yang menyimpan metadata yang digunakan oleh mesin virtual.

Item terakhir di baris (mis. 0.2300771 secs) Menunjukkan waktu yang dibutuhkan untuk melakukan pengumpulan; dalam hal ini kira-kira seperempat detik.

Format untuk koleksi utama di baris ketiga serupa.

Format keluaran yang dihasilkan -verbose:gcdapat berubah dalam rilis mendatang.

Saya tidak yakin mengapa ada PSYoungGen di dalam diri Anda; apakah Anda mengganti pemulung?

Michael Myers
sumber
Di mana menemukan file log gc?
Tuan Lou
7
Jawaban ini tidak benar-benar menjawab pertanyaan asli. Saya merasa jawaban michaeljoseph lebih baik. Ini menjawab pertanyaan yang diajukan oleh Ethan dan melakukan pekerjaan yang lebih baik dengan memecah contoh aslinya. Meskipun ada dua masalah dalam jawabannya (tautannya sekarang sudah mati dan rafa.ferreria telah menunjukkan yang lain), itu tidak hanya memuntahkan dokumen Oracle.
Dirk
127
  1. PSYoungGen mengacu pada pengumpul sampah yang digunakan untuk koleksi kecil. PS adalah singkatan dari Parallel Scavenge.
  2. Set angka pertama adalah ukuran sebelum / sesudah generasi muda dan set kedua untuk seluruh heap. ( Mendiagnosis masalah Pengumpulan Sampah merinci format)
  3. Nama menunjukkan generasi dan kolektor yang dimaksud, set kedua untuk seluruh heap.

Contoh GC penuh terkait juga menunjukkan kolektor yang digunakan untuk generasi lama dan permanen:

3.757: [Full GC [PSYoungGen: 2672K->0K(35584K)] 
            [ParOldGen: 3225K->5735K(43712K)] 5898K->5735K(79296K) 
            [PSPermGen: 13533K->13516K(27584K)], 0.0860402 secs]

Terakhir, uraikan satu baris keluaran log contoh Anda:

8109.128: [GC [PSYoungGen: 109884K->14201K(139904K)] 691015K->595332K(1119040K), 0.0454530 secs]
  • 107Mb digunakan sebelum GC, 14Mb digunakan setelah GC, ukuran generasi muda maks 137Mb
  • 675Mb heap digunakan sebelum GC, 581Mb heap digunakan setelah GC, ukuran heap maks 1Gb
  • GC minor terjadi 8109,128 detik sejak dimulainya JVM dan memakan waktu 0,04 detik
michaeljoseph
sumber
8
hanya komentar kecil, nilai antara '()' bukanlah ukuran maksimal, karena selamanya, adalah ukuran maksimal untuk saat ini. Jika GC tidak dapat membebaskan heap kurang dari itu maka batas lebih banyak ruang akan dibutuhkan untuk sistem operasional, dan nilai ini akan meningkat. Menghormati tentu saja batas yang ditentukan pada:
-Xmx
@ rafa.ferreira Saya rasa nilai dalam paranthesis yaitu 1119040K adalah ukuran tumpukan yang berkomitmen. Saya tidak berpikir, GC mencetak ukuran 'tumpukan maksimum' di mana pun. Referensi 1 dan Referensi 2
rohitmohta
23

Saya hanya ingin menyebutkan bahwa seseorang bisa mendapatkan log GC mendetail dengan

-XX:+PrintGCDetails 

parameter. Kemudian Anda melihat output PSYoungGen atau PSPermGen seperti pada jawaban.

Juga -Xloggc:gc.logtampaknya menghasilkan keluaran yang sama seperti -verbose:gctetapi Anda dapat menentukan file keluaran di pertama.

Contoh penggunaan:

java -Xloggc:./memory.log -XX:+PrintGCDetails Memory

Untuk memvisualisasikan data dengan lebih baik, Anda dapat mencoba gcviewer (versi yang lebih baru dapat ditemukan di github ).

Berhati-hatilah untuk menulis parameter dengan benar, saya lupa "+" dan JBoss saya tidak dapat dijalankan, tanpa pesan kesalahan!

Andrei
sumber
3
Perhatikan bahwa gc.log akan ditimpa ketika java di-restart (seperti, jika Anda me-restart tomcat Anda karena mengalami masalah memori, dan Anda ingin melihat gc.log itu). Atau setidaknya jika Anda merotasi log GC. Ada banyak opsi lain yang mengontrol gc logging. Lihat oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html . Secara khusus, pertimbangkan-XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<some number of files> -XX:GCLogFileSize=<some size> -XX:+PrintTenuringDistribution
Dan Pritts