컴퓨터공학/운영체제

스택과 힙의 차이 및 속도 차이가 나는 이유 (in 할당 / 해제)

듀IT 2022. 10. 10. 22:27

스택?

정의

스택(Stack): (보통 깔끔하게 정돈된, 차곡차곡 쌓은) 더미

  • 스택 메모리에는 함수 호출시 생성되는 ‘스택 프레임’이 쌓인다. (Stack Memory Allocation)
  • 스택 프레임에는 해당 함수의 지역 변수, 매개변수, 함수 실행 완료시 돌아갈 주소가 저장된다.
  • LIFO 구조로, 마지막에 들어온 스택 프레임(Top에 있는 스택프레임)이 가장 먼저 제거된다.

동작

  1. 함수 호출시 스택 영역에 스택 프레임을 쌓는다
  2. 함수를 실행한다.
  3. 함수가 실행을 끝마치면 해당 스택프레임을 스택에서 제거한다.

특징

  • 스택 영역에서 스택 프레임 생성 (변수 메모리 할당 등) 및 해제는 컴파일러에 정의된 루틴을 통해서 수행된다.
  • 연속적인 공간에 메모리가 할당된다.
  • 크기가 매우 작다… (윈도우: 1mb, 리눅스: 8 mb)
💡 스택의 메모리의 크기는 컴파일 시 결정된다. 따라서 낭비없이 연속적인 메모리 공간을 사용할 수 있다. 또한 메모리 할당과 해제에 대한 오버헤드가 없다!

힙?

정의

힙(Heap): (아무렇게나 쌓아 놓은) 더미

  • 힙 메모리는 동적으로 할당된 저장되는 공간이다.
  • 즉, 컴파일 당시 얼만큼의 메모리가 필요할지 예상할 수 없어서 프로그램 실행 중에 확인하여 할당하는 메모리이다.

특징

  • malloc, new 를 통해 동적으로 할당된 메모리는 힙 영역에 저장되며, 스택과 달리 scope를 벗어나도 자동으로 사라지지 않는다.
  • 따라서 힙 메모리는 할당한 사람이 책임지고 사용이 끝나면 해제해주어야 메모리 누수가 생기지 않는다. (Swift는 ARC가 메모리 관리를 해주므로, 개발자가 메모리 관리에 덜 신경 쓸 수 있다)
  • 불연속적인 공간(랜덤하게) 메모리가 할당된다.
💡 힙은 런타임에 동적으로 메모리 공간을 할당해주어야 한다. 불연속적인 공간에 메모리를 할당하기 때문에, 메모리 단편화가 발생할 수 있다.

 

스택이 힙보다 빠른 이유 : 첫번째

💡 스택은 컴파일 타임에 그 크기가 미리 정해지는 메모리이다.

 

  • 스택은 미리 정해진 크기를 따라 움직이기 대문에, 실행 중에 메모리를 계산하거나 판단할 일이 없다.
  • 즉 메모리 할당 / 해제로 인한 오버헤드가 없다.

스택이 힙보다 빠른 이유 : 두번째

💡 스택 포인터를 감소시킴으로써 스택 공간을 제한시킨다.

 

  • 스택 프레임을 스택에서 제거한다는 의미는, 실제로 메모리를 해제한다는 의미가 아니다.
  • 스택은 컴파일 타임에 이미 메모리가 고정된 것이므로, 프로그램 종료할 때까지 그 크기를 변경할 수 없다. 즉 메모리를 해제할 이유가 없다!
  • 단순히 스택 포인터(SP)를 감소시켜 남아있던 데이터는 스택 포인터가 다시 증가할 때 사용했던 공간을 단순히 덮어 쓰는 식으로 동작한다는 의미이다.
  • 스택 포인터를 변경하는 것은 매우 단순한 단일 CPU instruction이다.

함수가 종료되면 스택프레임이 스택에서 제거되는 것이 아니고 스택포인터(SP)의 위치만 움직인다.

힙이 스택보다 느린 이유 : 첫번째

💡 힙 메모리는 메모리 할당 / 해제 작업일 필요하다. (오버헤드 발생)

 

  • 힙 메모리는 메모리를 할당할 때 OS가 메모리를 훑으면서 할당 가능한 연속된 메모리 공간을 찾은 뒤에 반환해주어야 한다.
  • 할당시 요청된 데이터의 크기, 메모리 단편화 상황 등 다양한 요소를 고려하기 때문에, 더 많은 CPU instruction이 필요하다.
  • 메모리 해제시, 사용하던 메모리를 반환할 때 기존에 존재하던 큰 메모리와 병합하는데, 병합할 때 속도가 저하된다.

사용의 측면에서….힙이 스택보다 느린 이유 : 부가정보 1

💡 응용 프로그램에서 힙 블록을 적절하게 사용하지 않을 경우 힙이 손상된다.

 

이중해제(이미 해제했는데 다시 해제하는 것), 해제 후 블록 사용, 블록 경계를 벗어나 덮어쓰기 등등…

사용의 측면에서….힙이 스택보다 느린 이유 : 부가정보 2

💡 힙 경합이 발생하면 속도가 저하된다.

 

힙 경합: 두개 이상의 쓰레드에서 동시에 데이터에 접근하려고 하면 Lock이 걸리는 현상

Lock이 걸리면 한 쓰레드의 작업이 완료될 때까지 다른 쓰레드가 대기해야하므로, 반응속도가 떨어질 수 밖에 없다.

 

참고자료

https://woo-dev.tistory.com/89

https://www.geeksforgeeks.org/stack-vs-heap-memory-allocation/

https://blog.naver.com/PostView.naver?blogId=cjsksk3113&logNo=222274484731&parentCategoryNo=&categoryNo=31&viewDate=&isShowPopularPosts=true&from=search