StackOverflowError'ı Java'da yakalamak * hiç * iyi mi?


27

Öyle olmadığını düşünürdüm, ama dün yapmak zorunda kaldım. Asenkron işleri işlemek için Akka'yı (JVM için bir aktör sistemi uygulaması) kullanan bir uygulamadır . Oyunculardan biri bir miktar PDF manipülasyonu yapıyor ve kütüphane buggy olduğu için StackOverflowErrorher seferinde ölüyor .

İkinci yönü, herhangi bir JVM ölümcül hatanın (örneğin StackOverflowError) yakalanması durumunda Akka'nın tüm aktör sistemini kapatacak şekilde yapılandırılmış olmasıdır.

Üçüncü husus, bu oyuncu sisteminin bir web uygulamasına (WTF-ish, miras, nedenler için) yerleştirilmiş olmasıdır, bu nedenle oyuncu sistemi kapatıldığında web uygulaması değildir. Net etki, bir StackOverflowErroriş işleme uygulamamızın sadece boş bir web uygulaması haline gelmesidir.

Hızlı bir düzeltme StackOverflowErrorolarak, atılmayı yakalamak zorunda kaldım , böylece aktör sisteminin iplik havuzu bozulmadı. Bu bana, özellikle bu gibi durumlarda bu tür hataları yakalamanın belki de yolunda olabileceğini düşünmemi sağladı? Bir iş parçacığı havuzu keyfi görevleri işleme olduğunda? Bir aksine, bir uygulamanın tutarsız bir durumda OutOfMemoryErrornasıl bırakılabileceğini hayal edemiyorum StackOverflowError. Yığın böyle bir hatadan sonra silinir, böylece hesaplama normal şekilde devam edebilir. Ama belki de önemli bir şeyi özlüyorum.

Ayrıca, hatayı ilk etapta hatayı düzelttiğime dikkat edin (aslında birkaç gün önce bu aynı uygulamada bir SOE'yi düzelttim), ancak bunun ne zaman olduğunu bilmiyorum Böyle bir durum ortaya çıkabilir.

StackOverflowErrorİşi yakalamak yerine JVM işlemini yeniden başlatmak, bu işi başarısız olarak işaretlemek ve işime devam etmek neden daha iyi olsun ?

SOE'leri asla yakalayamamak için zorlayıcı bir sebep var mı? Bana hiçbir şey söylemeyen belirsiz bir terim olan "en iyi uygulamalar" dışında.


1
Başka bir seçenek de JVM'de mevcut olan yığın alanını arttırmak
cırcır böceği

3
@ ratchetfreak: StackOverflowExceptions genellikle sonlandırılmayan bir yöntem çağrısı zincirinden kaynaklanır - yığın alanını artırmak, yeni bir iş parçacığının bellek maliyetini hiçbir fayda sağlamaz.
jhominal,

1
Girdi çok büyük olduğu için en az bir SOE meşru idi. Ne yazık ki, özyinelemeli bir uygulama ile (Java'nın regex impl.) Ele alınması çok iyi bir fikir değildi. Yine de, hesaplamanın sona ermesi garantili olsa bile, yeni yığın boyutunun diğer hesaplamalar için yeterince büyük olup olmadığını bilmiyorsunuz.
Ionuț G. Stan

2
Bunun Sta'ya taşınması gerekmiyor mu ... Oh, bekle ... boşver. :-)
Blrfl

Buggy kütüphanenle ilgili. Bu pdf manipülasyon işlevini kendi sürecine geçirmelisiniz, böylece os'un onu öldürmesine izin verebilirsiniz.
Esben Skov Pedersen 20

Yanıtlar:


44

Genel bir kural olarak, bir şeyi yapmak kesinlikle, asla kabul edilemez olsaydı ve bununla ilgili bir anlaşma olsaydı, dil uygulayıcıları buna izin vermezdi. Neredeyse oybirliğiyle açıkça kesin olmayan makbuzlar yoktur. (Neyse ki, çünkü bu bizi insan programcılarının işlerinde tutar!)

Bu hatayı yakalamanın sizin için en iyi seçenek olduğu bir durum bulmuş gibi görünüyor: uygulamanızın çalışmasına izin verirken, diğer tüm alternatifler yapmaz ve sonuçta önemli olan şey budur. Tüm "en iyi uygulamalar" olabilir birçok durumda uzun deneyimler sadece toplamları olan genellikle zaman kazanmak için belirli bir olayın detaylı bir analizin yerine kullanılabilir; Senin durumunda, zaten belirli bir analiz yaptın ve farklı bir sonuç var. Tebrikler, bağımsız düşünce yeteneğine sahipsin!

(Bir yığın taşma uygulamasının sadece bir bellek tükenmesi gibi tutarsız bir uygulamada bırakabileceği durumlar vardır elbette. Sadece bir nesnenin inşa edildiğini ve sonra iç içe iç yöntem çağrıları yardımıyla başlatıldığını düşünün - eğer bir tanesi fırlarsa, nesne Muhtemelen bir tahsisat başarısız olmuş gibi, mümkün olması gerekmeyen bir durumda olabilir. Fakat bu, çözümünüzün hala en iyisi olamayacağı anlamına gelmez.)


3
Teşekkürler. Şüphelerim, .NET’in StackOverflowExceptionyakalanamaz bir istisna yaptığını öğrendikten sonra biraz güçlendi . Biliyorum, farklı bir platform, ama bir nedenleri olabileceğini düşündüm. Ayrıca, nesne başlatma konusundaki amacınız açıktır. Bu bana bu SOE'yi birkaç soyutlama katmanını yakalamalıyım ki “yanlış” SOE'yi yakalamamalıyım.
Ionuț G. Stan

14
+1: En iyi uygulamalar her zaman neden ve hangi bağlamda "en iyi" olduklarını açıklamalarla gelmelidir , böylece kendi durumunuza uygulanıp uygulanmayacağını yargılayabilirsiniz.
Michael Borgwardt

situations hereolmalı situations where.
Saat

2

JVM'ye özgü herhangi bir risk olup olmadığını burada bilmiyorum, ama genel olarak oldukça mantıklı görünüyor.

Örneğin, log(n)tipik bir durumda yığın derinliğine sahip olan saf hızlı erişim noktası gibi özyinelemeli algoritmalar vardır , ancak en kötü durumda n, yığını havaya uçurabilecek derinliğe düşer.

En kötü durum nadirdir ve kısmen sınıflandırılmış kümede sıralama yeniden başlatırsanız tekrar oluşması olası değildir; bu nedenle, ortaya çıktığında yığın taşması istisnasını yakalamak ve hatanın oluşmasını veya ölmesini önlemek yerine çalışmayı yeniden başlatmak çok mantıklı olur. tüm uygulama

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.