본문 바로가기

ETC

오버헤드, 스택 오버 플로우

참고) overhead란?

- 오버헤드는 프로그램 실행 흐름에서 나타나는 현상 중 하나로서 프로그램을 실행하는 도중에 동떨어진 위치의 코드가 실행하여 추가적인 시간, 메모리, 자원을 소요하는 현상이다. 

- 즉, 오버헤드는 특정 기능을 수행하는데 필요한 간접적 시간, 메모리 자원을 의미한다. 

 

스택 오버 플로우 

- 함수를 호출 하면 메모리의 콜 스택 영역에 매개변수, 지역변수, 반환주소값이 저장된다. 

- 재귀 함수의 경우 차곡차곡 쌓인 콜 스택이 하나 하나 씩 수행 하며 사라진다. 

- 메모리의 한계까지 콜 스택이 쌓일 경우 자바에서는 StackOverflowError가 발생하고 파이썬에서는 RecursionError가 발생한다. 

 

참고) 콜스택과 프로세스 힙

- 프로그램의 변수는 주로 콜 스택과 프로세스 힙에 저장된다.

- 프로세스 힙과 스택은 모두 실행중인 프로그램의 변수를 저장하는 메모리 영역으로서 힙의 경우 specific function에 묶여 있지 않아 다른 함수도 해당 영역을 안전하게 사용할 수 있다.

- 일반적으로 스택은 지역 변수만 접근하고 힙은 전역 변수에 접근할 수 있으며 스택은 고정된 영역이지만 힙은 동적 메모리 공간이다. 

- 예를들어 파이썬 재귀 함수 호출이 일정 횟수 이상일 경우 RecursionError(Stack Overflow)가 발생하며 이는 스택이 고정된 공간이기에 발생하는 문제이다.

- 반면 힙의 경우 C의 malloc 함수 등이 있으며 프로그램이 동작 중 별도의 메모리 공간을 만든다. 필요한 공간의 크기가 불분명 하기 때문에 힙과 같은 동적 메모리 공간에 들어간다. malloc() 은 힙 메모리에 공간이 할당됨과 동시에 stack frame에 그것의 포인터가 저장된다. 

- 함수 호출이 끝난 후 스택에 있는 변수들은 지워진다. 반면 힙에 있는 변수들은 자동으로 지워지지 않아 C언어 에서는 allocate로 할당을 해제해 주어야 한다. 자바에서는 garbage collector가 자동으로 힙 공간을 차지하고 있는 불필요한 객체들을 삭제해 준다. 자바와 같은 객체 지향 프로그램일수록 힙 공간이 가득 찬 탓에 객체가 더이상 생성되지 않아 동작에 문제가 발생하곤 한다.

- 스택에 할당된 메모리의 크기는 컴파일러가 가지고 있다. 함수가 호출 될 때 스택 메모리에 저장되며 함수 호출이 끝날 때마다 자동으로 해제 되므로 임시 메모리 할당이라고 한다. 따라서 스택 변수의 메모리 할당과 해제에 신경 쓸 필요가 없다. 

- 프로그래머가 할당하고 해제할 수 있는 메모리 공간을 힙이라고 부른다. 이는 힙 데이터 구조와 관련 없다. 객체를 만들 때마다 항상 힙 공간이 생성되고 참조 정보가 스택 메모리에 저장된다. 

- 스택 메모리에 비해 힙 메모리 할당은 안전하지 않다. 힙 메모리 공간에서의 데이터는 모든 스레드에서 엑세스 할 수 있기 때문에 이를 제대로 처리하지 않을 때 메모리 누수가 발생한다. 따라서 Garbage collector로 사용하지 않은 오래된 객체를 제거해야 한다.