And Brain said,
Stack & Heap, 기억에 대한 프로그래밍적 인식 본문
오늘은 프로그램이 운영체제로부터 할당받는 메모리 영역에 대해서 알아보도록 하자.
엄밀히 따지면 코드 영역과 데이터 영역 또한 메모리 공간에 할당되지만, 스택(Stack) 영역과 힙(Heap) 영역에 대해서만 간단히 알아볼 것이다.
스택과 힙 둘다 여러분의 코드상에서 런타임에 사용할 수 있는 메모리지만, 이들은 각기 다른 방식으로 구조화 되어있다.
스택(Stack)
스택은 값을 받아들인 순서대로 값을 저장하고 반대 방향으로 값을 지운다.
이것을 lifo(last in, first out)이라고 한다.
쌓여있는 접시를 생각해보면 된다.
여러분이 접시를 더 추가하려면 접시더미의 꼭대기에 쌓아올리고, 여러분이 접시가 필요해지면 꼭대기에서부터 한장 꺼낼 것이다.
중간이나 밑에서부터 접시를 추가하거나 제거하려고 시도하는건 힘들지 않겠는가?
데이터를 추가하는 것을 스택에 푸시하기 (pushing on the stack)라고 부르고, 데이터를 제거하는 것을 스택을 팝하기 (popping off the stack)라고 부른다.
스택은 데이터에 접근하는 방식 덕택에 빠르다.
이 방식은 새로운 데이터를 넣어두기 위한 공간 혹은 데이터를 가져올 공간을 검색할 필요가 전혀 없는데, 바로 그 공간이 항상 스택의 꼭대기(top)이기 때문이다!
스택을 빠르게 해주는 또다른 특성은 스택에 담긴 모든 데이터가 결정되어 있는 고정된 크기를 갖고 있어야 한다는 점이다.
힙(Heap)
컴파일 타임에 크기가 결정되어 있지 않거나 크기가 변경될 수 있는 데이터를 위해서는, 힙에 데이터를 저장할 수 있다.
힙은 스택보다 조금 더 복잡한데, 데이터를 힙에 넣을때, 먼저 저장할 공간이 있는지 물어보게 된다.
그러면 운영체제가 충분히 커다란 힙 안의 빈 어떤 지점을 찾아서 이 곳을 사용중이라고 표시하고, 해당 지점의 포인터를 우리에게 돌려준다.
이 절차를 힙 공간 할당하기(allocating on the heap)라고 부르고, 종종 그냥 "할당(allocating)"으로 줄여 부른다.
스택에 포인터를 푸싱하는 것은 할당에 해당되지 않고, 포인터는 결정되어 있는 고정된 크기의 값이므로, 우리는 스택에 포인터를 저장할 수 있지만, 실제 데이터를 사용하고자 할 때는 포인터를 따라가야 한다.
힙에 저장된 데이터에 접근하는 것은 스택에 저장된 데이터에 접근하는 것보다 느린데, 그 이유는 포인터가 가리킨 곳을 따라가야 하기 때문이다.
현대 프로세서들은 메모리 내부를 덜 뛰어다닐 때 더 빨라지게 된다.
유사한 예로, 여러 테이블로부터 주문을 받는 레스토랑의 웨이터를 생각해보라.
다음 테이블로 움직이기 전에 지금 테이블에서 모든 주문을 다 받는 것이 가장 효율적이지 않겠는가?
A 테이블에서 하나 주문 받고, 다시 B 테이블로 가서 하나 주문 받고, 다시 A로, 다시 B로 가며 하나씩 주문을 받으면 훨씬 느려질 것이다.
이와 마찬가지로, 프로세서는 (힙에 있는 데이터와 같이) 멀리 떨어져 있는 데이터들 보다는 (스택에 있는 것과 같이) 붙어있는 데이터들에 대한 작업을 하면 더욱 빨라지게 된다.
마찬가지로, 힙으로부터 큰 공간을 할당받는것 또한 시간이 걸릴 수 있다.
여기까지 스택과 힙에 대해 간단히 알아보았지만, 여러분들이 저수준으로 "내려갈" 언어를 다루지 않는다면, 대부분의 언어들은 Garbage Collector라는 아름다운 메모리 관리자들을 가지고 있기에 그렇게 자주 스택과 힙에 대한 생각을 할 필요가 없다.
물론 당신이 C/C++ 언어를 다룬다면 이러한 메모리 관리는 전적으로 개발자의 책임이므로 메모리 관리의 안정성이 상대적으로 많이 떨어지므로 스택과 힙 영역에 대한 이해도가 상당히 중요하다.
Thanks for watching, Have a nice day.
References
https://rinthel.github.io/rust-lang-book-ko/ch04-01-what-is-ownership.html
'IT > CS' 카테고리의 다른 글
Garbage Collector Stop-The-World(STW), 더 월드! (0) | 2023.05.11 |
---|---|
Garbage Collector, 프로그램의 스캐빈저 (0) | 2023.05.10 |
Kernel, 운영체제의 코어 (0) | 2023.03.26 |
TCP , UDP, IP 헤더 (2) | 2022.11.29 |
TCP/IP 계층 구조 및 역할 (3) | 2022.11.26 |