메모리 구조: 두 판 사이의 차이

기술노트
(CS 용어 정리 - 메모리 구조 추가)
 
편집 요약 없음
 
(같은 사용자의 중간 판 하나는 보이지 않습니다)
1번째 줄: 1번째 줄:
== 메모리 구조 ==
== 💻 프로그램 메모리 구조 ==


프로그램이 실행되기 위해서는 먼저 프로그램이 메모리에 로드(load)되어야 한다.
프로그램이 실행될 때, 운영체제(OS)는 정해진 방식에 따라 메모리를 여러 영역으로 나누어 할당합니다. 이 공간을 '''프로그램 메모리 구조'''라고 부르며, 각 영역은 저마다의 역할과 특징을 가집니다.


또한 프로그램이 실행되는 동안 CPU가 코드를 처리하기 위해서는, '''메모리가 명령어와 데이터들을 저장'''해야 한다.
[https://user-images.githubusercontent.com/65716445/205929196-7e1f59c0-3b2b-4db7-8e0c-9f9235af7ccd.png 메모리 구조 다이어그램 보기]


프로그램이 실행하게 되면 OS는 메모리(RAM)에 공간을 할당해준다.
----


<p align="center"><img width="700" alt="1" src="https://user-images.githubusercontent.com/65716445/205929196-7e1f59c0-3b2b-4db7-8e0c-9f9235af7ccd.png"></p>
=== 📂 4가지 메모리 영역 ===


> 프로그램이 운영체제로부터 할당받는 대표적인 메모리 공간
'''코드(Code) 영역'''


<p align="center"><img width="390" alt="1" src="https://user-images.githubusercontent.com/65716445/205929202-3c6f16ca-a42a-444c-afcb-ddc7d9db4b92.png"></p>
실행할 프로그램의 코드가 기계어 형태로 저장되는 공간입니다. CPU는 이 영역의 명령어를 순차적으로 가져가 처리하며, 데이터는 읽기만 가능하고 수정할 수는 없습니다.
* '''저장 정보''' : 소스 코드가 컴파일된 기계어
* '''특징''' : 읽기 전용(Read-Only)


=== 코드(code) 영역 ===
----


---
'''데이터(Data) 영역'''


* '''실행할 프로그램의 코드(=우리가 작성한 소스코드)가 저장되는 영역'''
프로그램이 시작될 때 생성되어 종료될 때까지 유지되는 변수들이 저장됩니다. 주로 프로그램 전체에서 사용되는 전역 변수나 static 변수가 여기에 해당합니다.
* 텍스트(text) 영역이라고도 한다.
* '''저장 정보''' : 전역 변수, 정적(static) 변수
* CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 된다.
* '''생명 주기''' : 프로그램 시작부터 종료까지
* 프로그램이 시작하고 종료될 때까지 메모리에 계속 남아있는다.


=== 데이터(data) 영역 ===
----


---
'''힙(Heap) 영역'''


* '''전역 변수''''''정적(static) 변수'''가 할당되는 영역
프로그래머가 원하는 시점에 동적으로 메모리를 할당하고 해제하는 공간입니다. Java에서 `new` 키워드로 객체를 생성하면 바로 이 힙 영역에 저장됩니다. 사용이 끝난 메모리는 직접 해제해주어야 하며, 그렇지 않으면 '메모리 누수(Memory Leak)'가 발생할 수 있습니다.
* 숫자나 문자열 값인 리터럴도 저장된다.
* '''저장 정보''' : 동적으로 생성된 객체, 인스턴스
* 프로그램의 시작과 동시에 할당되며, 프로그램이 종료되면 메모리에서 소멸한다.
* '''특징''' : 개발자가 직접 관리, 런타임에 크기 결정


=== 힙(heap) 영역 ===
----


---
'''스택(Stack) 영역'''


* 동적으로 할당된 변수가 할당되는 영역(Dynamic Memory Allocation)
함수가 호출될 때 생성되는 지역 변수와 매개변수가 임시로 저장되는 공간입니다. 함수 실행이 끝나면 저장되었던 데이터도 자동으로 사라지는 '후입선출(LIFO)' 구조를 가집니다. 속도가 매우 빠르다는 장점이 있습니다.
* 프로그래머가 직접 공간을 할당, 해제하는 메모리 공간
* '''저장 정보''' : 함수 내의 지역 변수, 매개변수
* 영역 중 유일하게 런타임 시 크기가 결정된다.
* '''특징''' : 함수 종료 시 자동 소멸, 빠른 속도
* 선입선출(FIFO) 구조로, 가장 먼저 들어온 데이터가 가장 먼저 인출된다.
  - 힙 영역이 '''메모리의 낮은 주소에서 높은 주소의 방향으로 할당'''
  되기 때문
  <p align="center"><img width="400" alt="1" src="https://user-images.githubusercontent.com/65716445/205929204-e56e5c2b-fbee-44b1-9746-d0c07a83cf7f.png"></p>


=== 스택(stack) 영역 ===
----


---
=== 🔥 스택 vs 힙 비교 ===


* 프로그램이 자동으로 사용하는 임시 메모리 영역
{| class="wikitable"
* 함수 호출 시 생성되는 지역 변수와 매개 변수가 저장되는 영역으로, 함수 호출이 완료되면 저장된 메모리도 해제된다.
! 구분 !! 스택 (Stack) !! 힙 (Heap)
* 스택 영역은 푸시(push) 동작으로 데이터를 저장하고, 팝(pop) 동작으로 데이터를 인출한다. → 후입선출(LIFO) 구조
|-
  - 스택 영역이 '''메모리의 높은 주소에서 낮은 주소의 방향으로 할당 되기 때문'''
! 관리 주체 || OS (자동) || 개발자 (수동)
|-
! 속도 || 매우 빠름 || 상대적으로 느림
|-
! 생명 주기 || 함수 호출 ~ 종료 || 직접 해제 전까지
|-
! 크기 || 작고 제한적 || 크고 유연함
|}


=== 오버 플로우 ===
----


---
=== ⚠️ 메모리 오버플로우 ===


<p align="center"><img width="400" alt="1" src="https://user-images.githubusercontent.com/65716445/205929206-a9b8fd77-1c59-427b-8eb3-2310c8989d2b.png"></p>
오버플로우는 각 영역이 할당된 메모리 공간을 넘어서는 현상입니다. 스택과 힙은 서로 마주보는 방향으로 메모리가 쌓이기 때문에, 한쪽이 너무 커지면 상대 영역을 침범하며 오버플로우가 발생할 수 있습니다.


* '''오버 플로우'''란 영어로 넘쳐흐른다는 뜻
* '''스택 오버플로우''' : 스택 공간이 부족하여 힙 영역을 침범하는 현상입니다. 주로 재귀 함수가 무한히 호출되거나 거대한 크기의 지역 변수를 선언했을 때 발생합니다.
* '''한정된 메모리 공간이 부족하여 메모리 안에 있는 데이터가 넘쳐 흐르는 현상'''
* '''힙 오버플로우''' : 힙 영역이 부족하여 스택 영역을 침범하는 현상입니다.


오버 플로우의 종류 중에 '''힙 오버 플로우'''와 '''스택 오버 플로우'''가 있다.
----


힙은 메모리 위쪽 주소부터 할당되고, 스택은 메모리 아래쪽 주소부터 할당되기 때문에 각 영역이 상대 공간을 침범하는 일이 발생할 수 있다.
=== 💡 개발자 핵심 Point ===


이때 '''힙이 스택을 침범하는 경우를 오버 플로우'''라 하고, '''스택이 힙을 침범하는 경우를 스택 오버 플로우'''라고 한다.
* 프로그램 메모리는 역할에 따라 '''코드, 데이터, , 스택''' 4가지 영역으로 나뉩니다.
 
* '''스택(Stack)'''은 '''자동으로 관리'''되고 속도가 빠르지만, 크기가 작아 함수 내의 '''임시 데이터''' 저장에 주로 사용됩니다.
=== 스택과 힙을 나눠놓은 이유 ===
* '''힙(Heap)'''은 개발자가 '''직접 관리'''하며 크기가 유연하여, 프로그램 전반에서 사용될 '''객체나 인스턴스'''를 저장하는 데 쓰입니다.
 
* 재귀 호출 시에는 종료 조건을 명확히 하여 '''스택 오버플로우'''가 발생하지 않도록 주의해야 합니다.
---
 
==== 스택 ====
 
스택은 매우 빠르게 접근과 할당이 가능하며 메모리에 낭비되는 공간 없이 사용가능하다.
 
스택의 의미대로 그냥 차례대로 쌓는 연속적인 메모리 영역이기 때문이다.
 
하지만 용량이 적어서 쓰기 힘들 수 있다.
 
==== 힙 ====
 
힙은 사용자가 따로 할당, 관리를 해서 사용해야하는 공간으로 스택보다는 느리게 할당된다.
 
용량은 크지만 단편화의 위험성을 가지고 있다.
 
\*단편화: 기억 장치의 빈 공간 또는 자료가 여러 개의 조각으로 나뉘는 현상
 
하지만 크기를 먼저 설정해주는 스택영역에서 보다 유연함을 가지고 있다.
 
반면에, 제대로 반환하지 않으면 Memory Leak(메모리 누수)이 일어나 메모리에 손해를 볼 수 있다.
 
==== 그렇다면 모든 영역을 단편화가 없는 스택으로 구현하면 안되나? ====
 
안된다!
 
스택의 특성상 데이터의 접근할 수 있는 부분은 top 뿐이다.
 
스택에 활성레코드가 저장될 수 있는 이유이자, 스택 자료구조를 적용할 수 있는 이유이며, 함수가 실행 중일때만 접근 가능한 공간이다.
 
따라서 중간에 접근하려고 해도 불가능한 경우가 많다.
 
→ 힙에 할당을 하게 되면 포인터로 해당 데이터에 접근이 가능하다.
 
==== 즉, ====
 
프로그램 상에서 얼마나 메모리가 필요할 지 모르는 상태이고,
 
미리 모두 할당해놓는 것은 쓰이지 않을 메모리까지 할당되어있는 비효율적인 상태에 놓일 수 있으므로
 
스택, 힙으로 나누어 할당을 하는 것이라고 할 수 있다.
 
> 참고자료
> [https://luv-n-interest.tistory.com/1046](https://luv-n-interest.tistory.com/1046)
> [https://lxxyeon.tistory.com/70](https://lxxyeon.tistory.com/70)
> [https://all-young.tistory.com/17](https://all-young.tistory.com/17)

2025년 9월 6일 (토) 01:36 기준 최신판

💻 프로그램 메모리 구조

프로그램이 실행될 때, 운영체제(OS)는 정해진 방식에 따라 메모리를 여러 영역으로 나누어 할당합니다. 이 공간을 프로그램 메모리 구조라고 부르며, 각 영역은 저마다의 역할과 특징을 가집니다.

메모리 구조 다이어그램 보기


📂 4가지 메모리 영역

코드(Code) 영역

실행할 프로그램의 코드가 기계어 형태로 저장되는 공간입니다. CPU는 이 영역의 명령어를 순차적으로 가져가 처리하며, 데이터는 읽기만 가능하고 수정할 수는 없습니다.

  • 저장 정보 : 소스 코드가 컴파일된 기계어
  • 특징 : 읽기 전용(Read-Only)

데이터(Data) 영역

프로그램이 시작될 때 생성되어 종료될 때까지 유지되는 변수들이 저장됩니다. 주로 프로그램 전체에서 사용되는 전역 변수나 static 변수가 여기에 해당합니다.

  • 저장 정보 : 전역 변수, 정적(static) 변수
  • 생명 주기 : 프로그램 시작부터 종료까지

힙(Heap) 영역

프로그래머가 원하는 시점에 동적으로 메모리를 할당하고 해제하는 공간입니다. Java에서 `new` 키워드로 객체를 생성하면 바로 이 힙 영역에 저장됩니다. 사용이 끝난 메모리는 직접 해제해주어야 하며, 그렇지 않으면 '메모리 누수(Memory Leak)'가 발생할 수 있습니다.

  • 저장 정보 : 동적으로 생성된 객체, 인스턴스
  • 특징 : 개발자가 직접 관리, 런타임에 크기 결정

스택(Stack) 영역

함수가 호출될 때 생성되는 지역 변수와 매개변수가 임시로 저장되는 공간입니다. 함수 실행이 끝나면 저장되었던 데이터도 자동으로 사라지는 '후입선출(LIFO)' 구조를 가집니다. 속도가 매우 빠르다는 장점이 있습니다.

  • 저장 정보 : 함수 내의 지역 변수, 매개변수
  • 특징 : 함수 종료 시 자동 소멸, 빠른 속도

🔥 스택 vs 힙 비교

구분 스택 (Stack) 힙 (Heap)
관리 주체 OS (자동) 개발자 (수동)
속도 매우 빠름 상대적으로 느림
생명 주기 함수 호출 ~ 종료 직접 해제 전까지
크기 작고 제한적 크고 유연함

⚠️ 메모리 오버플로우

오버플로우는 각 영역이 할당된 메모리 공간을 넘어서는 현상입니다. 스택과 힙은 서로 마주보는 방향으로 메모리가 쌓이기 때문에, 한쪽이 너무 커지면 상대 영역을 침범하며 오버플로우가 발생할 수 있습니다.

  • 스택 오버플로우 : 스택 공간이 부족하여 힙 영역을 침범하는 현상입니다. 주로 재귀 함수가 무한히 호출되거나 거대한 크기의 지역 변수를 선언했을 때 발생합니다.
  • 힙 오버플로우 : 힙 영역이 부족하여 스택 영역을 침범하는 현상입니다.

💡 개발자 핵심 Point

  • 프로그램 메모리는 역할에 따라 코드, 데이터, 힙, 스택 4가지 영역으로 나뉩니다.
  • 스택(Stack)자동으로 관리되고 속도가 빠르지만, 크기가 작아 함수 내의 임시 데이터 저장에 주로 사용됩니다.
  • 힙(Heap)은 개발자가 직접 관리하며 크기가 유연하여, 프로그램 전반에서 사용될 객체나 인스턴스를 저장하는 데 쓰입니다.
  • 재귀 호출 시에는 종료 조건을 명확히 하여 스택 오버플로우가 발생하지 않도록 주의해야 합니다.