Berk Akademi
Birebir ders başvurusu Ücretsiz ön görüşme Ana Sayfa

Java "java.lang.StackOverflowError" Hatası Nasıl Çözülür?

java-stackoverflowerror-hatasi-nasil-cozulur
Bu yazıda neler var?
  1. Java StackOverflowError neden oluşur ve ilk teşhis nasıl yapılır?
  2. Faktöriyel örneğinde sonlandırma koşulu nasıl düzeltilir?
  3. Stack trace içindeki tekrar eden çağrı nasıl izlenir?
  4. Özyineleme yerine döngü ne zaman daha uygundur?

Java java.lang.StackOverflowError hatası, çoğunlukla bir metodun kendisini ya da başka bir metodu durmadan çağırması nedeniyle oluşur. Çözüm, erişilebilir bir sonlandırma koşulu eklemek ve her çağrıda problemin veya girdinin küçüldüğünü doğrulamaktır.

İlk teşhiste çağrı zincirini ve stack trace bilgisini inceleyerek hatanın hangi metotta tekrarlandığını bulmalısın. JVM bellek ayarını değiştirmek, sonlandırılmayan çağrıyı düzeltmez; asıl çözüm kod akışındaki koşulları ve metot çağrılarını kontrol etmektir.

Java StackOverflowError neden oluşur ve ilk teşhis nasıl yapılır?

Java StackOverflowError neden oluşur ve ilk teşhis nasıl yapılır?

Çağrı yığını, çalışan bir programda açılmış metot çağrılarının tutulduğu bellek alanıdır. Bir metot başka bir metodu çağırdığında yığına yeni bir çağrı eklenir. Metot tamamlandığında çağrı yığından çıkar. Çağrılar durmadan eklenirse yığın yeni bir çağrıyı taşıyamaz ve StackOverflowError oluşabilir.

Stack trace ise hata oluştuğu anda çağrı yığını hakkında verilen metinsel rapordur. Bu raporda sınıf, metot ve çoğu zaman ilgili kaynak kodu satırı görülür. Stack trace canlı çağrı yığınının kendisi değildir, hatanın hangi çağrı zinciriyle oluştuğunu gösteren bir izdir.

Çağrı zinciri, bir metodun çağırdığı metotların ve bu metotların devam eden çağrılarının sıralı akışıdır. Bir metodun kendisini çağırması doğrudan özyineleme olarak adlandırılır. Örneğin sayac() metodunun yeniden sayac() çağırması bu duruma örnektir. Bir metodun ikinci bir metodu, ikinci metodun da ilk metodu çağırması ise dolaylı özyinelemedir.

Üç aşamalı teşhis

  1. Sonlandırma koşulunu kontrol et: Özyinelemeli çağrının durduğu en basit duruma base case denir. Bu koşul yoksa metot kendisini çağırmayı sürdürebilir.
  2. Girdinin küçülüp küçülmediğine bak: Her çağrı, problemi base case’e yaklaştırmalıdır. Örneğin n değerinin n - 1 hâline gelmesi küçülen bir girdiye örnektir. Girdi aynı kalıyor veya büyüyorsa çağrılar sona ulaşmayabilir.
  3. Çağrı zincirini izle: Hata yalnızca bir metodun kendisini çağırmasından kaynaklanmaz. İki ya da daha fazla metot arasında oluşan döngüsel çağrıları da incele.

Stack trace kontrolü için dört adım

  1. Hata türünü doğrula ve stack trace içinde java.lang.StackOverflowError satırını bul.
  2. at ile başlayan satırlarda tekrar eden sınıf, metot ve satır numaralarını işaretle.
  3. Tekrar eden çağrının kendi kodundaki satırını aç ve o satırda hangi metodun yeniden çağrıldığını belirle.
  4. Çağrıdaki argümanı ve koşulu izleyerek base case’e ulaşılıp ulaşılmadığını kontrol et.

Çağrı yığını, özyineleme ve metot akışını temel sorularla pekiştirmek için Java bilgi testini çözebilirsin.

Faktöriyel örneğinde sonlandırma koşulu nasıl düzeltilir?

Faktöriyel metodu, sonlandırma koşulu ile küçülen girdinin birlikte görülmesini sağlar. Aşağıdaki hatalı metotta ne bir base case vardır ne de çağrı argümanı değişir:

static int badFactorial(int n) {
    return n * badFactorial(n);
}

badFactorial metodu her seferinde aynı n değeriyle yeniden çağrılır. Çağrı geri dönmeden yeni bir çağrı yapıldığı için yöntem bir sonlandırma noktasına ulaşamaz ve sonunda StackOverflowError oluşur.

Doğru sürümde negatif giriş için açık bir politika belirlenir, 0 ve 1 için base case tanımlanır, diğer değerlerde ise n - 1 ile ilerlenir:

public class Main {
    static int factorial(int n) {
        if (n < 0) {
            throw new IllegalArgumentException("n negatif olamaz");
        }

        if (n == 0 || n == 1) {
            return 1;
        }

        return n * factorial(n - 1);
    }

    public static void main(String[] args) {
        System.out.println(factorial(0));
        System.out.println(factorial(1));
        System.out.println(factorial(5));
    }
}

n == 0 || n == 1 koşulu çağrıyı durdurur ve 1 döndürür. Bu, faktöriyel hesabının base case’idir. return n * factorial(n - 1) satırında önce daha küçük girdiye sahip çağrı yapılır, ardından dönen sonuç mevcut n değeriyle çarpılır.

Programın beklenen çıktıları, factorial(0), factorial(1) ve factorial(5) için sırasıyla 1, 1 ve 120 değerleridir:

1
1
120

Bu örnekte negatif n değeri sessizce geçiştirilmez. Metot, böyle bir girişte IllegalArgumentException fırlatır. Açık hata davranışı, geçersiz girdinin neden kabul edilmediğini kodu kullanan kişiye bildirir.

Stack trace içindeki tekrar eden çağrı nasıl izlenir?

Stack trace içindeki tekrar eden çağrı nasıl izlenir?

Tekrarlanan çağrıyı izlemek için stack trace içindeki uygulama koduna ait sınıf, metot ve satırları ayır; aynı çağrıların tekrarını, base case'e erişimi ve argümanın ilerleyip ilerlemediğini kontrol et.

Stack trace, hata anındaki metot çağrılarını gösterir. Çağrı yığını, etkin metot çağrılarını tutar. Çağrı zinciri ise başlangıç metodundan hatanın oluştuğu çağrıya kadar uzanan sıralı geçiştir. Base case, özyinelemeyi durduran koşuldur.

Aynı sınıf, metot ve satırın tekrarı güçlü bir ipucudur, ancak tek başına kök neden kanıtı değildir. Çağıran metot, girdiyi hazırlayan kod veya birbirini çağıran iki metot da incelenmelidir.

Aşağıdaki kısa örnekte n her çağrıda küçülür:

class Ornek {
    static int say(int n) {
        if (n == 0) return 0;
        return say(n - 1);
    }

    public static void main(String[] args) {
        System.out.println(say(3));
    }
}

Beklenen çıktı 0 değeridir. say(n) gibi değişmeyen bir çağrı, aynı satırın ilerlemeden tekrarlanmasına yol açabilir.

Sonlandırma koşulunu kontrol et: Metodun kendini çağırmayı bırakacağı koşul açık ve erişilebilir olmalıdır. Hiçbir çağrı bu koşula ulaşamıyorsa yığın büyümeye devam eder.

Girdinin veya durumun küçüldüğünü doğrula: Her çağrı, argümanı küçültmeli veya durumu çözüme yaklaştırmalıdır. Değişmeyen değerler sonsuz çağrı zinciri oluşturabilir.

Çağrı zincirini izle: Hata satırından geriye giderek çağrıyı kimin başlattığını ve girdinin nereden geldiğini bul. Kök neden, özyinelemeli metottan önceki hazırlık kodunda da olabilir.

  1. Hata başlığını ve uygulama koduna ait sınıf, metot ve satır bilgilerini ayır.
  2. Aynı metot ve satırın veya birbirini çağıran metotların tekrarını işaretle.
  3. İşaretli çağrıda base case'e erişilebilir mi ve argüman ya da durum her çağrıda ilerliyor mu kontrol et.
  4. Zinciri başlangıç çağrısına kadar izleyip sınır girdileriyle yeniden çalıştır ve kök nedeni düzelt.

Bu dört adımı farklı örneklerle pekiştirmek için Java hata ayıklama ve programlama yazılarına göz atabilirsin.

Özyineleme yerine döngü ne zaman daha uygundur?

Özyineleme, alt problem aynı yapıda doğal biçimde kendini yinelediğinde okunabilir olabilir. Basit doğrusal tekrar ve açık durum takibinde döngü daha anlaşılır bir seçenek olabilir. Bu nedenle hiçbir yaklaşım her durumda üstün değildir.

Ölçüt Özyineleme Döngü
Sonlandırma mantığı Base case ile durur; her çağrı bu koşula yaklaşmalıdır. Döngü koşulu ve güncellenen sayaç ya da durum ile durur.
Durumun ilerlemesi Argüman veya durum her çağrıda küçülür ya da çözüme yaklaşır. İlerleme aynı blokta açıkça görülür; güncelleme unutulursa döngü durmayabilir.
Doğal kullanım alanı Ağaç, klasör gibi iç içe yapıların ve benzer alt problemlerin tekrarlandığı durumlar. Dizi üzerinde gezinme, sayaç kullanımı ve basit doğrusal tekrar.
Yaygın hata riski Base case'e ulaşamama ve çağrı yığınının taşması. Koşulu veya sayaç güncellemesini unutma ve sonsuz döngü.

Faktöriyel örneğini doğrularken 0 ve 1 girdilerinde 1, 5 girdisinde 120 sonucunu; negatif girdilerde ise açıkça belirlenmiş reddetme politikasını kontrol et. Sonlandırma koşuluna gerçekten ulaşılıyor mu, çağrı argümanı her adımda ilerliyor mu ve stack trace içinde aynı satır ya da karşılıklı çağrı tekrar ediyor mu yeniden incele. JVM'nin yığın ayarını değiştirmek sonlanmayan çağrı zincirini düzeltmez; bu değişiklik kalıcı kök neden çözümü olarak görülmemelidir.

Bu teşhis adımlarını rehberli örneklerle çalışmak için birebir Java özel ders programını inceleyebilirsin.

Stack trace'i bu sırayla okumak, hatanın görünen satırından kök nedene doğru ilerlemeyi kolaylaştırır.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara