Saya sedang membaca buku tentang keterampilan pemrograman di mana penulis bertanya kepada orang yang diwawancarai, "Bagaimana Anda menabrak JVM?" Saya pikir Anda bisa melakukannya dengan menulis infinite untuk-loop yang pada akhirnya akan menggunakan semua memori.
Adakah yang punya ide?
Jawaban:
Hal yang paling dekat dengan satu "jawaban" adalah
System.exit()
yang mengakhiri JVM segera tanpa pembersihan yang tepat. Namun terlepas dari itu, kode asli dan kehabisan sumber daya adalah jawaban yang paling mungkin. Sebagai alternatif, Anda dapat mencari bug bug Sun di versi JVM Anda, beberapa di antaranya memungkinkan untuk skenario kerusakan berulang. Kami biasa mendapatkan crash semi-reguler ketika mendekati batas memori 4 Gb di bawah versi 32-bit (kami biasanya menggunakan 64-bit sekarang).sumber
Saya tidak akan menyebut melempar OutOfMemoryError atau StackOverflowError crash. Ini hanya pengecualian normal. Untuk benar-benar crash VM ada 3 cara:
Untuk metode terakhir, saya punya contoh singkat, yang akan menabrak Sun Hotspot VM dengan tenang:
Ini mengarah ke tumpukan overflow di GC sehingga Anda tidak akan mendapatkan StackOverflowError tetapi crash nyata termasuk file hs_err *.
sumber
java.lang.OutOfMemoryError: GC overhead limit exceeded
JNI . Bahkan, dengan JNI, menabrak adalah mode operasi standar. Anda harus bekerja ekstra keras agar tidak crash.
sumber
Gunakan ini:
Kelas ini harus di boot classpath karena menggunakan kode tepercaya, jadi jalankan seperti ini:
sumber
Field f = Unsafe.class.getDeclaredField( "theUnsafe" ); f.setAccessible( true ); unsafe = (Unsafe) f.get( null );
Bekerja sangat baik untuk saya.Unsafe
menurut definisi, "tidak aman". Ini sedikit curang.getDeclaredField
Trik kerja yang dikonfirmasi menggunakan JDK 8u131 di Linux x64, termasuk produksihs_err_pid*.log
dari aSIGSEGV
.Unsafe
bukan cheat. OP tidak mencari solusi 'bersih' untuk masalah pemrograman. Dia membutuhkan jvm untuk crash dalam cara yang paling buruk mungkin. Melakukan hal-hal asli yang jahat adalah apa yang dapat membuat itu terjadi, dan memang itulah yangUnsafe
terjadi.Saya datang ke sini karena saya juga mengalami pertanyaan ini di The Passionate Programmer , oleh Chad Fowler. Bagi mereka yang tidak memiliki akses ke salinan, pertanyaan dibingkai sebagai semacam filter / tes untuk kandidat yang mewawancarai posisi yang membutuhkan "programmer Java yang benar-benar baik."
Secara khusus, ia bertanya:
Saya telah memprogram di Jawa selama lebih dari 15 tahun, dan saya menemukan pertanyaan ini membingungkan dan tidak adil. Seperti yang ditunjukkan orang lain, Java, sebagai bahasa yang dikelola, dirancang khusus untuk tidak crash . Tentu saja selalu ada bug JVM, tetapi:
Seperti yang lain telah disebutkan, beberapa kode asli melalui JNI adalah cara yang pasti untuk menabrak JRE. Tetapi penulis secara khusus disebutkan dalam Java murni , jadi itu keluar.
Pilihan lain adalah memberi makan kode byte palsu JRE; cukup mudah untuk membuang beberapa data biner sampah ke file .class, dan meminta JRE untuk menjalankannya:
Apakah itu penting? Maksudku JRE itu sendiri belum jatuh; itu benar mendeteksi kode palsu, melaporkannya, dan keluar.
Ini memberi kita berbagai solusi yang paling jelas seperti meniup tumpukan melalui rekursi, kehabisan memori tumpukan melalui alokasi objek, atau hanya melempar
RuntimeException
. Tapi ini hanya menyebabkan JRE keluar denganStackOverflowError
pengecualian atau serupa, yang, sekali lagi bukan benar-benar crash .Jadi, apa yang tersisa? Saya benar-benar ingin mendengar apa yang sebenarnya ada dalam pikiran penulis sebagai solusi yang tepat.
Pembaruan : Chad Fowler merespons di sini .
PS: buku yang bagus. Saya mengambilnya untuk dukungan moral sambil belajar Ruby.
sumber
Kode ini akan merusak JVM dengan cara yang tidak menyenangkan
sumber
InternalError
dalam JDK 1.8. JVM tidak lagi gagal.Terakhir kali saya mencoba ini akan melakukannya:
Bagian pertama dari file log yang dihasilkan:
sumber
Implementasi JVM yang sempurna tidak akan pernah crash.
Untuk membuat crash JVM, selain dari JNI, Anda perlu menemukan bug di VM itu sendiri. Infinite loop hanya mengkonsumsi CPU. Mengalokasikan memori yang tidak terbatas seharusnya hanya menyebabkan OutOfMemoryError dalam JVM yang dibangun dengan baik. Ini mungkin akan menyebabkan masalah untuk utas lainnya, tetapi JVM yang baik tetap tidak crash.
Jika Anda dapat menemukan bug dalam kode sumber VM, dan misalnya menyebabkan kesalahan segmentasi dalam penggunaan memori implementasi VM, maka Anda benar-benar dapat crash.
sumber
Jika Anda ingin membuat crash JVM - gunakan yang berikut ini di Sun JDK 1.6_23 atau di bawah ini:
Ini disebabkan oleh bug di Sun JDK - juga ditemukan di OpenJDK. Ini diperbaiki dari Oracle JDK 1.6_24 dan seterusnya.
sumber
Tergantung pada apa yang Anda maksud dengan crash.
Anda dapat melakukan rekursi tak terbatas untuk membuatnya kehabisan ruang stack, tetapi itu akan crash "anggun". Anda akan mendapatkan pengecualian, tetapi JVM itu sendiri akan menangani semuanya.
Anda juga dapat menggunakan JNI untuk memanggil kode asli. Jika Anda tidak melakukannya dengan benar maka Anda dapat membuatnya sulit. Debugging crash itu adalah "menyenangkan" (percayalah, saya harus menulis C ++ DLL besar yang kita sebut dari applet java yang ditandatangani). :)
sumber
Buku Java Virtual Machine oleh Jon Meyer memiliki contoh serangkaian instruksi bytecode yang menyebabkan JVM ke dump inti. Saya tidak dapat menemukan salinan buku ini. Jika ada orang di luar sana, silakan cari dan kirimkan jawabannya.
sumber
pada winxpsp2 w / wmp10 jre6.0_7
Desktop.open (uriToAviOrMpgFile)
Hal ini menyebabkan thread yang muncul untuk melemparkan Throwable yang tidak tertangkap dan crash hotspot
YMMV
sumber
Perangkat keras yang rusak dapat merusak program apa pun. Saya pernah mengalami crash aplikasi yang dapat direproduksi pada mesin tertentu sambil bekerja dengan baik pada mesin lain dengan pengaturan yang sama persis. Ternyata mesin itu memiliki RAM yang rusak.
sumber
cara terpendek :)
sumber
Exception in thread "main" java.lang.StackOverflowError at Test.main
. Saya menggunakan jdk1.8.0_65Bukan crash, tapi lebih dekat ke crash daripada jawaban yang diterima menggunakan
System.exit
Anda dapat menghentikan JVM dengan menelepon
Runtime.getRuntime().halt( status )
Menurut dokumen: -
sumber
berikut adalah penjelasan terperinci tentang apa yang menyebabkan JVM ke dump inti (yaitu crash): http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_17534
sumber
Jika Anda ingin berpura-pura kehabisan memori, Anda bisa melakukannya
Saya tahu beberapa cara untuk menyebabkan JVM membuang file kesalahan dengan memanggil metode asli (yang dibangun di dalam), tetapi mungkin yang terbaik Anda tidak tahu bagaimana melakukan ini. ;)
sumber
Jika Anda mendefinisikan crash sebagai proses batal karena situasi tidak tertangani (yaitu tidak ada Pengecualian atau Kesalahan Java), maka ini tidak dapat dilakukan dari dalam Java (kecuali jika Anda memiliki izin untuk menggunakan kelas sun.misc.Unsafe). Ini inti dari kode terkelola.
Kecelakaan umum dalam kode asli terjadi dengan mendeferensier pointer ke area memori yang salah (alamat nol atau tidak selaras). Sumber lain dapat berupa instruksi mesin ilegal (opcodes) atau sinyal tidak tertangani dari pustaka atau panggilan kernel. Keduanya dapat dipicu jika JVM atau pustaka sistem memiliki bug.
Misalnya kode JITed (dihasilkan), metode asli atau panggilan sistem (driver grafis) dapat memiliki masalah yang menyebabkan crash nyata (itu cukup umum untuk mendapatkan crash ketika Anda menggunakan fungsi ZIP dan mereka kehabisan memori). Dalam kasus-kasus tersebut penangan kecelakaan JVM menendang dan membuang negara. Itu juga bisa menghasilkan file inti OS (Dr. Watson pada Windows dan core dump pada * nix).
Di Linux / Unix Anda dapat dengan mudah membuat crash JVM dengan mengirimkannya sinyal ke proses yang sedang berjalan. Catatan: Anda tidak boleh menggunakan
SIGSEGV
ini, karena Hotspot menangkap sinyal ini dan melemparkannya kembali sebagai NullPointerException di sebagian besar tempat. Jadi lebih baik mengirimSIGBUS
contoh.sumber
JNI adalah sumber besar gangguan. Anda juga dapat crash menggunakan antarmuka JVMTI karena itu perlu ditulis dalam C / C ++ juga.
sumber
Jika Anda membuat proses utas yang secara tak terhingga memunculkan lebih banyak utas (yang menghasilkan lebih banyak utas, yang ...) pada akhirnya Anda akan menyebabkan kesalahan stack overflow di JVM itu sendiri.
Ini memberi saya output (setelah 5 menit, perhatikan ram Anda)
sumber
Jika dengan "crash" yang Anda maksud adalah pembatalan JVM yang tiba-tiba, seperti yang akan menyebabkan JVM menulis ke hs_err_pid% p.lognya , Anda dapat melakukannya dengan cara ini.
Atur argumen-Xmx ke nilai yang sangat kecil dan beri tahu JVM untuk memaksakan crash pada outemmory:
Untuk menjadi jelas, tanpa argumen kedua di atas, itu hanya akan mengakibatkan jvm berakhir dengan OutOfMemoryError, tetapi tidak akan "crash" atau tiba-tiba membatalkan jvm.
Teknik ini terbukti membantu ketika saya mencoba untuk menguji JVM -XX: ErrorFile arg, yang mengontrol di mana log hs_err_pid harus ditulis. Saya telah menemukan posting ini di sini, ketika mencoba menemukan cara untuk memaksa crash seperti itu. Ketika saya kemudian menemukan hal di atas berfungsi sebagai yang termudah untuk kebutuhan saya, saya ingin menambahkannya ke daftar di sini.
Akhirnya, FWIW, jika ada yang bisa menguji ini ketika mereka sudah memiliki nilai -Xms yang ditetapkan di args Anda (ke beberapa nilai yang lebih besar dari di atas), Anda akan ingin menghapus atau mengubah itu juga, atau Anda tidak akan mendapatkan crash tetapi hanya kegagalan jvm untuk memulai, melaporkan "Ukuran tumpukan awal diatur ke nilai yang lebih besar dari ukuran tumpukan maksimum". (Itu tidak akan jelas jika menjalankan JVM sebagai layanan, seperti dengan beberapa server aplikasi. Sekali lagi, itu menggigit saya, jadi saya ingin membagikannya.)
sumber
Jika Anda mengubah infinite for loop ke panggilan rekursif ke fungsi yang sama, maka Anda akan mendapatkan pengecualian stack overflow:
sumber
Saya melakukannya sekarang, tetapi tidak sepenuhnya yakin bagaimana ... :-) JVM (dan aplikasi saya) terkadang hilang sepenuhnya. Tidak ada kesalahan yang dilemparkan, tidak ada yang dicatat. Berganti dari bekerja menjadi tidak berjalan sama sekali secara instan tanpa peringatan.
sumber
Terpendek? Gunakan kelas Robot untuk memicu CTRL + BREAK. Saya melihat ini ketika saya mencoba untuk menutup program saya tanpa menutup konsol (Itu tidak memiliki fungsi 'keluar').
sumber
Apakah ini masuk hitungan?
Ini hanya berfungsi untuk Linux dan dari Java 9.
Untuk beberapa alasan saya tidak mendapatkan,
ProcessHandle.current().destroyForcibly();
tidak membunuh JVM dan melemparjava.lang.IllegalStateException
pesan penghancuran proses saat ini tidak diperbolehkan .sumber
Menjalankan ke masalah ini ketika mencoba untuk meniru kecelakaan JVM.
Jni bekerja, tetapi perlu di-tweak untuk platform yang berbeda. Akhirnya, saya menggunakan kombinasi ini untuk membuat crash JVM
-XX:+CrashOnOutOfMemoryError
long[] l = new long[Integer.MAX_VALUE];
untuk memicu OOMKemudian JVM akan crash dan menghasilkan crash log.
sumber
Jika 'Crash' adalah sesuatu yang mengganggu jvm / program dari terminasi normal, maka pengecualian yang tidak ditangani dapat melakukan ini.
Jadi, itu tergantung pada jenis CRASH apa ?!
sumber
ArithmeticException
merupakan