Bagaimana cara andal mengambil Java Heap Dumps?

9

Tim saya mengalami kesulitan ketika mencoba untuk melakukan heap dump yang dipicu oleh OutOfMemoryErrors. Untuk alasan tertentu kami saat ini mengambil dump dengan jmap dipanggil dari skrip bash alih-alih menggunakan bendera HeapDumpOnOutOfMemoryError. Kami menggunakan JVM 64-bit 1.6 dengan ukuran tumpukan sekitar 3 GB. Tumpukan tumpukan kami gagal 90% dari waktu (perkiraan).

Apakah ada yang bisa kita lakukan untuk meningkatkan peluang kita mendapatkan timbunan sampah yang bersih yang bisa kita gunakan untuk memecahkan masalah memori? Saya telah membaca bahwa jmap memiliki masalah besar di Jawa 1.4 tetapi masalah-masalah itu sebagian besar harus diatasi sekarang.

Karlcyr
sumber
4
Saya menominasikan pertanyaan ini untuk "terdengar menjijikkan paling tidak disengaja".
phoebus
1
Hah- Saya berpikir untuk membuatnya terdengar menjijikkan tapi saya baru di sini dan saya tidak yakin bagaimana masyarakat akan menerimanya :).
karlcyr

Jawaban:

7

Yang mana sistem operasi Anda? (Saya tidak bisa menambahkan komentar).

Untuk Solaris, kami mendapatkan hasil yang lebih baik, pertama-tama memaksa dump inti ( gcore <pid>) dan kemudian melampirkan jmap ke file dump inti ( jmap -heap:format=b <path to java bin> <path to core>)

gcoreadalah utilitas * nix untuk menghasilkan gambar dari program yang sedang berjalan. Lihat tautan .

fglez
sumber
mencobanya dengan gdb di linux dan itu berfungsi dengan baik.
Christian
JDK mana yang memiliki "gcore"? milikku, Sun 32 bit jdk untuk linux 1.6.0.20 tidak memilikinya.
djangofan
Diedit dengan klarifikasi gcore.
fglez
2

kami memiliki JSP yang menanyakan ManagementFactory.getThreadMXBean () dan menghasilkan laporan. Mungkin tidak berguna saat aplikasi mogok, tetapi jika Anda melakukan jajak pendapat setiap menit, Anda akan mengetahui apa yang terjadi.

Info lebih lanjut di sini.

rytis
sumber
2

Anda dapat memonitor aplikasi Anda melalui jmx dari luar. ketika Anda mengetahui beberapa metrik yang mengindikasikan OutOfMemory yang akan datang, Anda bisa memicu jmap berjalan sebelum pengecualian dilempar.

Kristen
sumber
Terima kasih Christian- apakah jmap lebih bisa diandalkan sebelum kesalahan dilemparkan?
karlcyr
jmap masih membutuhkan waktu untuk membuat Anda mendapatkan heap dump. tetapi Anda akan mendapatkan heapdump penuh selama jvm / tomcat Anda yang paling bertanggung jawab.
Christian
Saya pikir alat terbersih dan termudah untuk melakukan ini adalah "Visual VM". Mungkin di luar ruang lingkup tetapi membuat plugin khusus untuk VisualVM yang mendeteksi kondisi dan mengambil dump otomatis dari dalam VisualVm akan menjadi IMHO yang luar biasa.
Djangofan
2

Terima kasih untuk semua saran Anda.

Yang akhirnya kami lakukan adalah menulis skrip untuk secara aktif memantau log pengumpulan sampah. Dalam pengalaman kami, back-to-back Full GC hampir selalu mendahului OOM, jadi skrip kami mendeteksi peristiwa ini, dengan anggun menghapus server dari kumpulan penyeimbang beban, dan memaksa tumpukan timbunan. Ini telah sangat meningkatkan efektivitas kami.

Karlcyr
sumber
2

Ini adalah pertanyaan yang cukup lama, tetapi saya akan menjawab dengan harapan bahwa seseorang dapat menemukan ini berguna.

jmap memiliki opsi -F (force). Ini terbukti tidak berhasil dengan baik di masa lalu bagi saya. Jika Anda ingin menggunakan opsi -F, saya akan merekomendasikan Anda juga menentukan direktori java.io.tmp sebagai bagian dari perintah jmap. Ada masalah dengan JVM versi 1.6.22 di mana utilitas jmap tidak berfungsi dengan baik karena pengaturan direktori temp.

Anda juga dapat mencoba mengambil dump inti melalui gdb. Setelah Anda memiliki inti, jmap dapat mengubah inti menjadi tumpukan tumpukan.

Nick Hristov
sumber