---
# System prepended metadata

title: 학습활동
tags: [학습활동]

---

# 메모리의 구조

팀원 : BMO🤖, Serena🐷

### 메모리의 구조

#### Q. 컴퓨터의 주기억장치는 어떤어떤 영역을 가지고 있을까?
컴퓨터의 주기억장치란?
- CPU와 직접 자료를 교환할 수 있는 장치.
- 기본적인 명령어와 데이터를 기억.
- RAM / ROM로 구성
    **RAM(Random Access Memory)**
    : 임시 기억 장치. 찾는 자료 위치를 순차적으로 찾아가는게 아니라 어느 특정 위치에 직접 자료를 검색하고 저장하는 방법이다. CPU를 도와 명령 처리를 도와주며, 컴퓨터의 활동을 기억하고 있다가 다시 필요할 때 빠른 속도로 기억을 불러온다.
    통상적으로 메모리는 보통 기억장치에 있는 주기억장치, 특히나 RAM을 의미한다. 프로그램을 구동하기 위해서 운영체제가 메모리(RAM)에 데이터 및 명령어를 저장할 공간을 할당하여 준다.
    **ROM(Read Only Memory)**
    : 읽기 전용 기억 장치. 컴퓨터의 전원이 끊어져도 내용이 유지되며, 컴퓨터 기본 운영 체제 기능이나 언어해석장치(interpreter)를 내장하고 있다. 내용 변경이 불가능해서 고쳐쓰거나 삭제할 수 없다.
    
- 메모리는 **코드(code)**, **데이터(data)**, **스택(stack)**, **힙(heap)** 영역으로 구성된다.

![](https://hackmd.io/_uploads/Skb8MN4vn.png)

**code 영역**

: 사용자가 작성한 프로그램 `함수들의 코드`가 CPU에서 수행할 수 있는 기계어 명령 형태로 변환되어 저장되는 공간. 컴파일(compile) 타임에 결정되고 중간에 코드를 바꿀 수 없게 Read-Only 로 되어있다.
 
**data 영역**

: 전역 변수 또는 static 변수 등 `프로그램이 사용하는 데이터`를 저장하는 공간. 전역 변수 또는 static 값을 참조한 코드는 컴파일이 완료되면 data 영역의 주소값을 가르키도록 바뀐다. 전역변수가 변경 될 수도 있어 Read-Write로 되어있다. Swfit의 경우 static의 기본 동작이 lazy이기 때문에 프로그램 실행과 동시에 메모리에 할당되지는 않고 값에 접근할때 메모리 할당이 될 것으로 예상한다.

 ![](https://hackmd.io/_uploads/B1ri54Vwn.png)

**stack 영역**
 : 호출된 함수의 수행을 마치고 복귀할 주소 및 데이터(지역변수, 매개변수, 리턴값 등)를 임시로 저장하는 공간. 이 영역은 함수 호출시 기록하고 함수의 수행이 완료되면 사라진다. stack은 LIFO(Last In First Out) 방법을 따른다. 컴파일 시 stack 영역의 크기가 결정되기 때문에 무한정 할당 할 수 없다. 따라서 재귀함수가 반복해서 호출되거나 함수가 지역변수를 메모리를 초과할 정도로 너무 많이 가지고 있다면 `stack overflow`가 발생한다. -> Struct
 쓰레드별로 개별적으로 가지고 있는 메모리
 
**heap 영역**

 : 프로그래머가 필요할 때마다 사용하는 메모리 영역. 자바에서는 객체가 heap영역에 생성되고 GC에 의해 정리된다. Swift에서는 참조 타입의 값이 heap 영역에 할당되고 ARC에 의해 메모리 할당 해제된다. heap 영역은 컴파일 타임에 결정되고 런타임때 실행된다. heap은 자신의 영역 외로 확장하려고 하면 `heap Overflow`라는 것이 발생한다. -> class
쓰레드끼리 공유하는 메모리

![](https://hackmd.io/_uploads/rJGcXVNvh.png)


### ARC

#### Q. ARC는 무엇인가?
`Automatic Reference Counting`
: 객체와 그의 연관관계의 라이프타임 수명을 모델링. Swift에서 앱의 메모리 사용을 관리하기 위해 사용하는 기능. 자동으로 참조 횟수를 관리하기 때문에 대부분의 경우에 개발자는 메모리 관리에 신경쓸 필요가 없고 ARC가 알아서 더이상 사용하지 않는 인스턴스를 메모리에서 해지한다. 하지만 몇몇의 경우 ARC에서 메모리 관리를 위해 코드의 특정 부분에 대한 관계에 대한 정보를 필요로 한다. 참조 횟수는 클래스 타입의 인스턴스에만 적용되고 값 타입인 구조체, 열거형 등에는 적용되지 않는다.

#### Q. ARC 이전의 메모리 관리는 어땠을까?
`MRC(Manual Reference Counting)`으로 힙에 메모리를 직접 할당/해제 해주었다.
직접 메모리 할당을 위해 `retain`, 해제를 위해 `release` 함수를 사용했다.

#### Q. ARC를 이해해야 하는 이유는 무엇무엇이 있을까?
ARC의 장점으로 메모리 관리의 편의성, 안전성 등을 꼽을 수 있다. 이러한 장점들이 있기 때문에 ARC에 대한 이해가 필요하다고 생각한다.

1. 편리한 메모리 관리
ARC를 사용하면 개발자는 객체의 수명 주기를 직접 추적하고 메모리를 할당 및 해제하는 작업을 자동으로 처리할 수 있다. 이로써 개발자는 더 안전하고 편리하게 메모리 관리를 수행할 수 있다. ARC를 이해하고 사용함으로써 개발자는 메모리 관리 작업에 더 집중할 필요 없이 코드 작성에 집중할 수 있다.

2. 메모리 누수 방지
ARC는 객체의 참조 카운트를 추적하여 메모리를 자동으로 할당 및 해제한다. 개발자는 명시적인 메모리 관리 작업을 수행하지 않아도 되므로, 메모리 누수를 방지할 수 있다. 메모리 누수는 프로그램이 실행되는 동안 계속해서 메모리를 점유하고 사용하지 않는 객체가 늘어나는 현상이다. ARC를 이해하고 사용함으로써 개발자는 메모리 누수를 줄일 수 있다.

3. 댕글링 포인터 방지
ARC는 객체의 참조가 존재하는 동안에만 해당 객체를 유지한다. 참조가 더 이상 없는 경우 자동으로 메모리를 해제한다. 이를 통해 댕글링 포인터 오류를 방지할 수 있다. 댕글링 포인터는 이미 해제된 메모리를 참조하는 포인터로, 프로그램의 안정성과 정확성을 저하시킬 수 있는 오류이다.
    > 댕글링 포인터(dangling pointer)
    > 더 이상 유효하지 않은 메모리 위치를 참조하는 포인터

#### Q. 언제 구조체를 선택하고 언제 클래스를 선택해야할까?
구조체에 값 타입, 클래스는 참조타입이다. 공식문서를 참고하면 구조체를 기본적으로 사용하는 것을 권장한다. 참조 타입의 의도치 않은 공유를 방지하기 위해 값 타입을 사용하는 것이 좋다. 참조 타입(Class)을 사용하는 경우 ARC를 통해 메모리를 관리한다.
> 의도치 않은 공유 : 순환 참조, 이 클래스를 참조하면서 예기치 않게 값이 바뀔 수 있다.
- 값 타입 : Struct, Enum
- 참조 타입 : Class


### 📚 참고링크
- [🍎 Apple Docs - ARC](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/automaticreferencecounting/)
- [🍎 Apple Docs - Choosing Between Structures And Classes](https://developer.apple.com/documentation/swift/choosing-between-structures-and-classes)
- [🌐 Blog - iOS 메모리 관리](https://babbab2.tistory.com/26)

overHead????