본문 바로가기
자바

메모리와 StackOverFlow

by 진믈리 2024. 6. 28.

stack에 메모리가 지속적으로 쌓인다면

1. 메모리 구조와 상황

 

hip 영역의 메모리는 낮은 주소에서 높은 주소로 할당되고 stack 역역은 높은 주속에서 낮은 주소의 방향으로 할당된다. 

한정된 메모리 크기에 stack 메모리가 지속적으로 쌓인다면 어떻게 되는지 알아보았다.

 

자바의 메모리 구조

 

 

 

 

 

 

2. 실험코드

public class Main {
    public static void main(String[] args) {
        int cnt = 0;
        run(cnt);
    }

    static String run(int cnt){
        cnt++;
        System.out.println("재귀호출" + cnt);
        run(cnt);
        return "탈출!";
    }
}

 

 위의 실험코드를 보면 main() 메서드에서 run() 메서드를 호출 후 run() 메서드 안에서 무한 재귀호출을 하였다.  

 

2-1 실험 코드 메모리 스냅샷

run() 메서드를 제일 처음 호출 하였을때의 스냅샷이다.

클래스들의 놀이터인 static 영역에는 java.lang 패키지와 Main Class가 올라간 것을 확인할 수 있다.

stack 영역은 메서드들의 놀이터라고 했다. 스택 역역을 확인해 보면 main() 메서드 프레임과 run() 스택프레임이 배치된 것을 확인할 수있다.

물론 System.out.println() 도 메서드이다. 하지만 메시지 출력후 소멸되기에 이번 실험에서는 그림에서 생략하도록 하겠다.

 

만약 여기서 run() 메서드를 한번더 호출을 하면 어떻게 될까

 

 

 

위의 메모리 스냅샷을 보면 run() 메서드를 한번더 호출 하기 전 run() 메서드 내에서 cnt++; 이라는 코드를 먼저 마주치게 되어 1의 매개변수를 가진 run()스택프레임이 하나 더 생기게 되었다. 하지만 한번이 끝이 아니다 지금의 코드는 무한 재귀에서 빠져나오지 못하고 있다. run() 스택프레임(2), (3), (4) 무한정 생겨날 것이다.

 

2-2  코드 실행

코드를 실행시켜보니 12083번째에서 StackOverFlowError가 발생했다. 알고리즘 문제를 많이 풀어본 사람이라면 한번쯤은 마주쳐 봤을 에러일 것이다.  스택 메모리가 한계에 도달하여 경고를 날린것이다.

 

3. OutOfMemory

반대로 hip 메모리 공간이 부족하면 어떻게 될까? 궁금한 사람들은

int[] maxInt = new int[Integer.MAX_VALUE];

위 코드를 작성하고 실행시켜 보길 바란다 그러면 OutOfMemoryError를 만날 수 있을것이다.

'자바' 카테고리의 다른 글

java11과 17의 차이  (0) 2024.09.03
객체지향 설계 5원칙  (0) 2024.07.06
자바의 메모리 구조  (0) 2024.06.28
쓰레드의 동기화  (0) 2024.06.26