본문 바로가기
Python

Recursion Limit (재귀 호출 제한)

by yororing 2024. 7. 10.

00 개요

  • 목적: 회사에서 코드 분석 시 sys.setrecursionlimit(30000)로 재귀 호출의 최대 수(깊이)를 30000으로 늘리는 코드를 봤는데, 이 말이 무슨 의미인지 정리하고자 함
  • Recursion Limit에 대해 알아보고자 함

 

01 Recursion 방식이란

1. 정의

  • recursion: '재귀'
  • 우리는 목표를 달성하기 위해 어떠한 메소드 안에서 또 다른 메소드 호출 가능
  • 이와 유사하게 메소드는 자기 스스로 또한 호출 가능
  • Recursion(재귀) 방식은 programming technique 중 하나로 어떤 메소드가 목적을 달성하기 위해서 본인 스스로를 호출할 수 있는 메소드를 말함
  • Python에는 Recursion Limit(재귀의 한도)시스템의 안정을 위해 1000번으로 정해져있음  (기본값 = 1000)
  • 기본 재귀 깊이를 초과하면 RecursionError가 발생하지만, 재귀 깊이를 늘려서 에러 방지 가능함

2. Recursion Limit 설정 이유

1) 무한 재귀 방지

  • Stack Overflow 방지:
    • 재귀 호출이 너무 깊어지면 시스템 스택 메모리가 가득 차고 프로그램이 충돌 가능
    • 재귀 제한을 설정하면 무한 재귀로 인한 스택 오버플로우를 방지 가능
    • Stack Overflow: Stack 영역의 메모리가 지정된 범위를 넘어갈 때 발생하는 에러
      • Stack 메모리
        • 지역 변수가 저장되는 영역
        • 함수에서 지역 변수를 선언하면 지역 변수는 Stack 메모리에 할당되고 함수를 빠져나오면 Stack 메모리에서 해제됨
        • 하나의 프로그램이 실행될 때 수많은 함수를 호출하고 빠져 나오게 되는데 그 때마다 함수에서 사용하는 지역 변수는 Stack 영역에 할당되고 해제되는 것을 반복하게 되며 그에 따라 사용하는 Stack 영역도 변함
  • 안정성 향상:
    • 제한을 설정함으로써 의도하지 않은 무한 재귀로부터 프로그램을 보호하여 안정성 향상

2) 시스템 리소스 보호

  • 메모리 사용 관리:
    • 깊은 재귀 호출은 많은 메모리를 사용할 수 있음
    • 재귀 깊이를 제한함으로써 메모리 사용을 관리하고 시스템 리소스를 보호 가능
  • 성능 유지:
    • 무한 재귀가 발생하면 시스템 성능에 큰 영향을 줄 수 있음
    • 재귀 깊이를 제한하여 성능 저하를 예방 가능

3) 디버깅 용이

  • 디버깅 도움:
    • 재귀 호출의 깊이에 제한을 두면 코드가 의도한 대로 작동하지 않을 때 어디서 문제가 발생했는지 파악하기 쉬움
    • 제한이 없다면 디버깅이 어려울 수 있음

4) 알고리즘 특성

  • 특정 알고리즘 요구사항:
    • 일부 알고리즘은 깊은 재귀 호출이 필요할 수 있음
    • 예) 복잡한 트리나 그래프 구조를 탐색할 때 깊은 재귀 호출이 필요할 수 있음
    • 이 경우 재귀 제한을 적절히 늘려 알고리즘이 정상적으로 작동하도록 함

3. Recursion Limit 을 늘리는 이유

1) 재귀적 알고리즘

  • 어떤 알고리즘들은 깊은 재귀 호출이 필요
  • 예) 복잡한 그래프 탐색이나 백트래킹 알고리즘은 재귀 호출이 깊어질 수 있음

2) 데이터 구조

  • 큰 트리나 중첩된 데이터 구조를 처리할 때, 각 노드를 재귀적으로 방문해야 할 경우 깊은 재귀 호출이 필요할 수 있음

3) 특정 라이브러리 요구사항

  • 일부 라이브러리나 프레임워크는 내부적으로 깊은 재귀를 사용하여 작업을 수행
  • 이 경우 재귀 제한을 늘려야 정상적으로 동작 가능

4. Recursion Limit을 늘릴 시 주의사항

  • 재귀 깊이를 늘릴 때는 프로그램이 무한 재귀에 빠지지 않도록 주의해야 함
  • 재귀 깊이를 과도하게 설정 시 스택 오버플로우 및 시스템 메모리 부족 문제를 일으킬 수 있음 
  • 메모리 사용량을 모니터링하고, 시스템 성능에 미치는 영향을 고려해야 함
  • 가능한 경우, 반복문을 사용하여 재귀 호출을 대체하는 것이 더 안전하고 효율적일 수 있음 

02 Recursion Limit 설정

0. sys 라이브러리 참조

>>> import sys

1. Recursion Limit (재귀 한도) 확인

  • 현재 재귀 한도 값 (Python interpreter stack의 최대 깊이)을 반환
  • 이 한도(limit)는 무한 재귀(infinite recursion)로 인해 C stack이 overflow되고 Python이 충돌(crash)하는 것을 방지함
>>> import sys
>>> sys.getrecursionlimit()
>>> 1000    # 기본값 = 1000

 

2. Recursion Limit 설정

  • Python에는 재귀의 한도가 시스템의 안정을 위해 1000번으로 정해져있음
  • 재귀가 1000번을 넘어갈 것 같을 때, 그 한도를 풀어줘야 Recursion Error를 방지 가능
>>> sys.setrecursionlimit(n)

>>> sys.setrecursionlimit(30000) # 예시
>>> sys.getrecursionlimit()
>>> 30000

참조

  1. https://cdragon.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Recursion-and-Backtracking%EC%9E%AC%EA%B7%80-%EB%B0%B1%ED%8A%B8%EB%9E%98%ED%82%B9#:~:text=%EC%9D%B4%EC%99%80%20%EC%9C%A0%EC%82%AC%ED%95%98%EA%B2%8C%20%EB%A9%94%EC%86%8C%EB%93%9C%EB%8A%94,%EC%88%98%20%EC%9E%88%EB%8A%94%20%EB%A9%94%EC%86%8C%EB%93%9C%EB%A5%BC%20%EB%A7%90%ED%95%A9%EB%8B%88%EB%8B%A4. 
  2. https://velog.io/@smkim104/Python3-%EC%B5%9C%EB%8C%80-%EC%9E%AC%EA%B7%80%ED%95%9C%EB%8F%84-%EA%B9%8A%EC%9D%B4-%EC%84%A4%EC%A0%95-Maximum-recursion-depth-exceed 
  3. (stack overflow란) https://keepdev.tistory.com/21 
  4. https://docs.python.org/3/library/sys.html