Dulu saya berpikir itu bukan, tapi kemarin saya harus melakukannya. Ini adalah aplikasi yang menggunakan Akka (implementasi sistem aktor untuk JVM) untuk memproses pekerjaan yang tidak sinkron. Salah satu aktor melakukan beberapa manipulasi PDF, dan karena perpustakaannya bermasalah, ia mati StackOverflowError
setiap saat.
Aspek kedua adalah bahwa Akka dikonfigurasi untuk mematikan seluruh sistem aktornya jika ada kesalahan fatal JVM (mis. StackOverflowError) tertangkap.
Aspek ketiga adalah bahwa sistem aktor ini tertanam di dalam aplikasi web (untuk WTF-ish, warisan, alasan), jadi ketika sistem aktor dimatikan, aplikasi web tidak. Efek bersihnya adalah bahwa pada StackOverflowError
aplikasi pemrosesan pekerjaan kita menjadi hanya aplikasi web kosong.
Sebagai perbaikan cepat saya harus menangkap StackOverflowError
pelemparan, sehingga kumpulan benang dari sistem aktor tidak dirobohkan. Ini membuat saya berpikir bahwa mungkin kadang-kadang tidak apa-apa untuk menangkap kesalahan seperti itu terutama dalam konteks seperti ini? Kapan ada kumpulan thread yang memproses tugas sewenang-wenang? Tidak seperti OutOfMemoryError
saya tidak dapat membayangkan bagaimana seorang StackOverflowError
dapat meninggalkan aplikasi dalam keadaan tidak konsisten. Tumpukan dihapus setelah kesalahan seperti itu, sehingga perhitungan dapat berjalan secara normal. Tapi mungkin aku melewatkan sesuatu yang penting.
Juga, perlu dicatat bahwa saya semua untuk memperbaiki kesalahan di tempat pertama (sebenarnya saya sudah memperbaiki BUMN di aplikasi yang sama beberapa hari yang lalu), tapi saya benar-benar tidak tahu kapan ini situasi semacam itu mungkin muncul.
Mengapa lebih baik memulai kembali proses JVM daripada menangkap StackOverflowError
, menandai pekerjaan itu gagal, dan melanjutkan bisnis saya?
Apakah ada alasan kuat untuk tidak pernah menangkap BUMN? Kecuali "praktik terbaik", yang merupakan istilah tidak jelas yang tidak memberi tahu saya apa pun.
sumber
StackOverflowException
s biasanya karena rantai panggilan metode yang tidak berhenti - meningkatkan ruang stack kemudian akan meningkatkan biaya memori utas baru tanpa manfaat.:-)
Jawaban:
Sebagai aturan umum, jika sama sekali tidak pernah dapat diterima untuk melakukan sesuatu, dan ada kesepakatan tentang itu, para pelaksana bahasa tidak akan mengizinkannya. Hampir tidak ada maksim yang jelas seperti itu. (Untungnya, karena itulah yang membuat kami programmer manusia dalam pekerjaan!)
Tampaknya sangat seolah-olah Anda telah menemukan situasi di mana menangkap kesalahan ini adalah pilihan terbaik untuk Anda: itu memungkinkan aplikasi Anda bekerja, sementara semua alternatif lain tidak, dan itulah yang terpenting pada akhirnya. Semua "praktik terbaik" hanyalah ringkasan dari pengalaman panjang dengan banyak kasus yang biasanya dapat digunakan sebagai pengganti analisis rinci dari kasus tertentu untuk menghemat waktu; dalam kasus Anda, Anda sudah melakukan analisis spesifik dan mendapat hasil berbeda. Selamat, Anda mampu berpikir mandiri!
(Yang mengatakan, pasti ada situasi di mana stack overflow mungkin meninggalkan aplikasi tidak konsisten seperti kelelahan memori. Bayangkan saja beberapa objek dibangun dan kemudian diinisialisasi dengan bantuan panggilan metode internal bersarang - jika salah satu dari mereka melempar, objek tersebut mungkin dalam keadaan tidak seharusnya menjadi mungkin, seperti jika alokasi telah gagal. Tapi itu tidak berarti bahwa solusi Anda masih belum menjadi yang terbaik.)
sumber
StackOverflowException
pengecualian yang tidak bisa ditangkap. Saya tahu, ini platform yang berbeda, tetapi saya pikir mereka mungkin punya alasan. Juga, poin Anda berkaitan dengan inisialisasi objek tepat. Ini membuat saya berpikir bahwa saya harus menangkap SOE ini beberapa lapisan abstraksi di bawah, sehingga saya tidak menangkap SOE yang "salah".situations here
seharusnyasituations where
.Saya tidak tahu apakah ada risiko spesifik JVM di sini, tetapi secara keseluruhan tampaknya cukup masuk akal.
Sebagai contoh ada algoritma rekursif, seperti quicksort naif, yang memiliki
log(n)
kedalaman tumpukan dalam kasus khas, tetapi dalam kasus terburuk mereka menurun ke kedalamann
yang dapat meledakkan tumpukan.Kasus terburuk jarang terjadi, dan tidak mungkin terjadi lagi jika Anda me-restart mengurutkan pada set yang diurutkan sebagian, sehingga masuk akal untuk menangkap pengecualian stack overflow ketika itu terjadi dan memulai kembali pekerjaan alih-alih mencoba mencegah kesalahan terjadi atau membunuh seluruh aplikasi.
sumber