잉?

Exception in thread "main" java.lang.StackOverflowError 해결 + 상호 참조 본문

에러메시지,에러해결

Exception in thread "main" java.lang.StackOverflowError 해결 + 상호 참조

Jye_647 2023. 5. 31. 20:54

키오스크 주문 프로그램을 만드는 과정에 스택오버플로우 에러를 해결했다.

스택오버플로우는 지정한 메모리 사이즈에 비해 훨씬 많은 메모리를 사용하게 되어 발생하는 에러다.

즉, 내가 매고 있는 가방에 책도 넣고, 노트북도 넣고,  의자도 넣고, 책상도 넣다 찢어져 버린 상태이다.

 

에러들을 살펴보자.

에러들을 하나씩 눌러보면 (아래부터 위로 올라간다.)

Buy 클래스 ↓

Kiosk  kiosk  new  Kiosk();

Kiosk 클래스

Data  data  new  Data();

Data 클래스 ↓

Buy buy = new Buy();

이런 식으로 서로의 기본생성자를 불러온다.

 

스택오버플로우의 대표적인 사례가 재귀함수를 예로 들 수 있다는데 나의 경우엔 상호 참조의 사례이다.

클래스 간에 서로의 생성자를 불러오면서 연쇄적인 관계를 이루게 된다.

밑의 그림과 같이 끊임없이 서로를 불러냄으로써 메모리가 꽉 차게 되고 결국 넘치게 되는 것!

이것저것 살펴본 결과 필요하지 않은 생성자를 불러옴으로서 오류가 난 것이다.

 

Kiosk kiosk = new Kiosk(); // 필요 없는 코드XXXXX
 
 public void buyYesOrNo(int choice, String name, double price, String explanation) {
        if(choice == 1){
            basket = new ArrayList<>();
            basket.add(new ProductMenu(name, price, explanation));
            System.out.println(name + "가 장바구니에 추가되었습니다.\n");
            System.out.println("-----------------------------------------------------");
        }else {
            System.out.println("주문이 취소되었습니다.\n처음으로 돌아갑니다.");
            System.out.println("-----------------------------------------------------");
            System.out.println();
            kiosk.start(); // kiosk의 start메소드를 부르지 않아도 switch문을 통해 돌아간다.
        }
}

 

Buy클래스에서 kiosk 객체를 지워주니 해결되었다.

연쇄적인 관계 중 하나를 끊으면 서로를 불러오지 않게 되고 메모리가 쌓일 이유가 없어진다.

즉, 설계를 잘못했기에 스택오버플로우가 발생한 것이다. 

 

막연히 생성자를 불러다 쓰고 어떤 기능을 하는지 정확하게 파악하지 않고 사용하니깐 이런 불상사가 생겨났다. 

조금씩 과제를 진행하면서 이 기능은 왜 사용하는지 차근차근 살펴봐야겠다.

 


 

스택 오버 플로우(SOF) - Incheol's TECH BLOG

함수를 호출할 때 함수의 파라미터, 리턴 값, 복귀 주소 등을 스택에 저장한다. 재귀 함수를 사용하면 호출한 함수가 종료되지 않은 채 새로운 함수를 호출하므로 스택에 메모리가 계속적으로

incheol-jung.gitbook.io

 

Comments