Chap.4 ownership
· 50 min read
소유권(Ownership)
은 가비지 컬렉터가 없는 러스트에서 메모리 안정성을 보장하는 비결입니다.
이는 러스트에서 가장 특별한 기능이며, 어떻게 동작하는지 반드시 이해 해 둬야 합니다.
따라서 이번 장에서는 소유권을 비롯해 소유권과 관련된 빌림(Borrowing)
, 슬라이스(Slice)
기능과 러스트에선 데이터를 메모리에 어떻게 저장하는지 알아보겠습니다.
4.1 소유권이 뭔가요?
- 모든 프로그램은 작동하는 동안 컴퓨터의 메모리 사용 방법을 관리해야 합니다.
- 몇몇 언어는 가비지 컬렉션으로 프로그램에서 더 이상 사용하지 않는 메모리를 끊임없이 찾는 방식을 채용했고, 다른 언어는 프로그래머가 직접 명시적으로 메모리를 할당하고 해제하는 방식을 택했습니다.
- 이때 러스트는 제 3의 방식을 택했습니다. '소유권(ownership)' 이라는 시스템을 만들고, 컴파일러가 컴파일 중 검사할 여러 규칙을 정해 메모리를 관리하는 방식이죠.
- 이 방식은 프로그램 실행 속도에 악영향을 줄 일이 없습니다. 컴파일 타임에 전부 해결하니까요.
스택, 힙 영역
러스트 같은 시스템 프로그래밍 언어에서는 값을 스택에 저장하느냐 힙에 저장하느냐의 차이가 프로그램의 동작 및 프로그래머의 의사 결정에 훨씬 큰 영향을 미칩니다.
스택, 힙 둘 다 여러분이 작성한 프로그램이 런타임 중 이용할 메모리 영역이라는 공통점이 있지만 구조는 각각 다릅니다.
- 스택은 값이 들어온 순서대로 저장하고, 역순으로 제거합니다. 이를 last in, fist out 이라 하죠
- 스택에 저장되는 데이터는 모두 명확하고 크기가 정해져 있어야 합니다.
- 컴파일 타임에 크기를 알 수 없거나, 크기가 변경될 수 있는 데이터는 스택 대신 힙에 저장됩니다.
- 힙은 스택보다 복잡합니다.
- 데이터를 힙에 넣을때 먼저 저장할 공간이 있는지 운영체제한테 물어봅니다. 그럼 메모리 할당자는 커다란 힙 영역 안에서 어떤 빈 지점을 찾고, 이 지점은 사용 중이라고 표시한 뒤 해당 지점을 가리키는 포인터(pointer) 를 우리한테 반환합니다. 이 과정을 힙 공간 할당(allocating on the heap), 줄여서 할당(allocation) 이라 합니다 (스택에 값을 푸시하는 것은 할당이라 부르지 않습니다). 포인터는 크기가 정해져 있어 스택에 저장할 수 있으나, 포인터가 가리키는 실제 데이터를 사용하고자 할 때는 포인터를 참조해 해당 포인터가 가리키는 위치로 이동하는 과정을 거쳐야 합니다.
- 스택 영역은 데이터에 접근하는 방식상 힙 영역보다 속도가 빠릅니다.
- 메모리 할당자가 새로운 데이터를 저장할 공간을 찾을 필요가 없이 항상 스택의 가장 위에 데이터를 저장하면 되기 때문이죠.
- 반면에 힙에 공간을 할당하는 작업은 좀 더 많은 작업을 요구하는데, 메모리 할당자가 데이터를 저장하기에 충분한 공간을 먼저 찾고 다음 할당을 위한 준비를 위해 예약을 수행해야 하기 때문입니다.
- 힙 영역은 포인터가 가리키는 곳을 찾아가는 과정으로 인해 느려집니다.
- 현대 프로세서는 메모리 내부를 이리저리 왔다 갔다 하는 작업이 적을수록 속도가 빨라지는데, 힙에 있는 데이터들은 서로 멀리 떨어져 있어 프로세서가 계속해서 돌아다녀야 하기 때문이죠.
- 힙 영역처럼 데이터가 서로 멀리 떨어져 있으면 작업이 느려지고, 반대로 스택 영역처럼 데이터가 서로 붙어 있으면 작업이 빨라집니다. 이외에도, 큰 공간을 할당하는 작업도 힙 영역의 속도를 늦추는 요인입니다.
- 여러분이 함수를 호출하면, 호출한 함수에 넘겨준 값(값 중엔 힙 영역의 데이터를 가리키는 포인터도 있을 수 있습니다)과 해당 함수의 지역 변수들이 스택에 푸시됩니다.
- 그리고 이 데이터들은 함수가 종료될 때 pop 됩니다.
- 코드 어느 부분에서 힙의 어떤 데이터를 사용하는지 추적하고, 힙에서 중복되는 데이터를 최소화하고, 쓰지 않는 데이터를 힙에서 정리해 영역을 확보하는 등의 작업은 모두 소유권과 관련되어 있습니다.
- 반대로 말하면 여러분이 소유권을 한번 이해하고 나면 스택, 힙 영역으로 고민할 일이 줄어들 거란 뜻이지만, 소유권의 존재 이유가 힙 데이터의 관리라는 점을 알고 있으면 소유권의 동작 방식을 이해하는데에 도움이 됩니다.