CS나 Swift 문법 관련된 포스팅을 하면서,
'객체는 클래스란 틀을 바탕으로 메모리 상에 할당되는 결과물(Object)'
'Swift의 상수와 변수, 그리고 저장 프로퍼티는 메모리 상에 저장'
위와 같이 [메모리]라는 단어를 자주 사용해 왔습니다.
그런데, 실제로 메모리는 단일한 구조가 아닌
4가지의 공간, 구조로 구성되어 있다고 하는데 말입니다..
이번 포스팅에서는 해당 구조에 대해 살펴보는 시간을 가져볼까 합니다.
(ARC와 같은 면접 단골문제와도 연관되어 있으니, 반드시 짚고 넘어가야겠지요?)
메모리란 무엇인가요?
주 기억장치인 하드웨어 RAM을 의미하며, 프로그램을 실행하기 위한 정보를 저장
컴퓨터에서 동작하는 모든 프로그램은
RAM이란 기억장치 내 고유한 영역을 할당받습니다.
즉, RAM = 메모리로 인지하셔도 무방합니다.
그런데, 왜 영역이 구분되어 있을까요?
당연하게도, 메모리의 공간은 한정되어 있으니
보다 효율적으로 프로그램을 실행될 수 있도록 하기 위함입니다.
메모리의 영역과 주요 특징
- 메모리는 크게 4가지(Code, Data, Heap, Stack) 영역으로 나뉘어져 있습니다.
- 빌드를 통해 실행파일로 만들면, OS는 정보를 파악하여 메모리 공간에 할당합니다.
- 그렇게 되면, OS는 코드를 읽고(Read), 쓰며(Write) 동작을 시작합니다.
메모리의 4개 영역
언어별 차이는 존재하지만, 메모리는 크게 4개 영역(Code, Data, Heap, Stack)으로 구분된다
앞서 메모리는 4개 영역으로 구분된다고 살펴보았습니다.
그렇다면, 각각의 영역은 어떤 데이터가 저장되는 특징을 가지고 있을까요?
Code 영역 - 컴파일 단계
- [Code]영역은 코드를 실행하기 위해 기계어로 저장되는 영역입니다.
- 쉽게 말해, 개발자의 작성한 프로그램의 코드가 할당되는 영역입니다.
- 일종의 명령어(제어문, 함수, 상수)가 해당 영역에 저장됩니다.
- Swift의 경우 컴파일(Compiled) 시점에 할당되므로, 정적할당 메모리입니다.
Data 영역 - 컴파일 단계
- [Data]영역은 전역변수나 Static(정적)변수가 저장되는 영역입니다.
- 전역(Global)변수는, 코드 내에서 어디서든지 사용 가능한 변수를 의미합니다.
- 이는 특정 컨텍스트(Context) 외부에 위치하고 있는 변수입니다.
var nickname: String = "Lime"
var number: Int = 486
- 정적(Static)변수는, 전역변수와 반대로 특정 컨텍스트 내부에 선언된 변수입니다.
- 구조체, 클래스 등 특정 블럭 내부에 위치하며, 외부에서 접근할 수 있는 변수입니다.
- 변수명 앞에 'static' 이란 키워드가 함께 사용됩니다.
(인스턴스를 별도로 생성하지 않고, 해당 구조체나 클래스에서 바로 접근)
struct fruits {
static var apple: String = "사과"
}
fruits.apple // "사과"
Heap 영역 - 런타임 단계
- [Heap]영역은 개발자, 사용자에 의해 할당하며, 해제되는 관리 가능한 영역입니다.
- 클래스 인스턴스(Class Instance)나 클로저와 같은 '참조타입' 값이 저장됩니다.
- 데이터 크기가 확실하지 않으므로, 4개 영역 중 유일하게 런타임 시 할당됩니다.
class Profile {
var jason: String? // 변수 jason -> 동적 할당영역 Heap
var lime: String? // 변수 lime -> 동적 할당영역 Heap
func nickname() {} // 메서드 -> Heap
}
- Swift의 경우, 자동으로 메모리 할당/해제를 수행합니다.
- C언어의 경우, Dynamic Allocation(동적할당)함수를 활용, 할당/해제합니다.
- 하지만, Swift는 ARC(Auto Reference Counting) 기능을 통해 자동으로 관리합니다.
- 즉, 메모리의 할당과 해제가 활발하게 이뤄지는 동적 할당영역에 포함됩니다.
Stack 영역 - 컴파일 단계 - 동적영역 & 정적할당
- [Stack]영역은 프로그램이 자동적으로 할당, 해제하는 임시 메모리 영역입니다.
- 함수를 호출할 경우, 지역변수나 매개변수, 리턴값 등이 저장되는 영역입니다.
- 함수가 종료될 경우, 해당 함수에 할당된 변수를 메모리 상에서 자동으로 해제합니다.
func multiply(_ a: Int, _ b: Int) -> Int { // 매개변수 a,b -> 동적할당 Stack 할당
let result = a * b // 지역변수 result -> 동적할당 Stack 할당
return result // 리턴값 result -> 동적할당 Stack 할당
}
- 💡 주의! Stack은 컴파일 단계에서 메모리가 할당하는 정적 할당이나, 해당 메모리 공간은 동적 영역입니다.
메모리 구조의 4가지 영역에 대해 살펴보았습니다.
하지만,
"Heap과 Stack은 어떤 차이가 있는지?"
"메모리 주소(Address)란 무엇인지?"
"ARC의 개념과 주요 기능은?"
여전히 풀리지 않는 의문들이 산더미입니다.
이후 포스팅에서는
위 궁금증을 차근 차근 해결해보는 시간을 가져볼까 합니다.
'CS > Computer Basic' 카테고리의 다른 글
[CS/Basic] 메모리 관리의 시작, ARC(Automatic Reference Counting) (0) | 2023.03.16 |
---|---|
[CS/Basic] 메모리 영역, Heap과 Stack엔 어떤 데이터가 쌓일까? (1) | 2023.02.23 |
[CS/Basic] 객체지향 프로그래밍의 특징과 설계원칙(SOLID) (2) | 2023.02.01 |
[CS/Basic] 마침내, 객체지향 프로그래밍 (OOP, Object-Oriented Programming) (0) | 2023.01.25 |
[CS/Basic] 절차적 프로그래밍은 '절차지향'이 아니다! (0) | 2023.01.05 |
댓글