본문 바로가기
개발자 준비/운영체제

[OS] 메인 메모리 구조 -3

by osul_world 2022. 5. 24.
728x90

멀티 프로세싱과 멀티 스레딩을 공부하면서, 공유자원과 컨텍스트 스위칭 등 메모리와 관련된 내용이 많아 한번 정리하고자 한다.

 

이전 편에서 컴퓨터 시스템 구조 중 메인 메모리 부분이 있었다.

 

프로세스가 실행되기 위해선 리소스가 보조 메모리로 부터 메인 메모리에 할당되어야 하는데, 이는 CPU가 메인 메모리에만 직접 접근이 가능하기 때문이다.

 

메인 메모리는 아래와 같이 두가지로 구분할 수 있다.

 

메인 메모리 구분

메인 메모리 유저 영역, 커널 영역 2가지로 분리된다.

  • 유저 영역: 일반 프로그램을 위한 메모리 영역
  • 커널 영역: 운영체제를 위한 메모리 영역, 운영체제의 핵심인 커널이 위치하는 메모리

 

운영체제는 부팅과 동시에 메인 메모리에 할당되어 상주하는 최초의 프로그램이라고 했었다.

커널 영역은 이 운영체제가 존재하는 메인 메모리의 영역이라고 생각하면 된다.

 

 

유저 영역 메모리 구조

일반적으로 사용자가 이용하게 되는 메모리이다. 사용자가 사용하고자 하는 프로세스들은 이 영역에 할당되어 실행된다.

 

스택 영역, 힙 영역, 데이터 영역, 코드 영역으로 나뉜다.

 

ROM은 Read Only 값이 변하지 않는 데이터를 저장

RAM은 Read / Write  값이 변하는 데이터를 저장

 

 

 

Stack 영역

  • 함수의 호출과 관계되는 지역변수매개변수가 저장되는 영역입니다.
  • 함수의 호출과 함께 할당되며 함수의 호출이 완료되면 소멸합니다.
    • 이렇게 Stack영역에 저장되는 함수의 호출정보를 Stack Frame이라고 합니다.
  • 할당과 해제를 반복하기 때문에 데이터 용량이 불확실합니다. 프로그램이 자동으로 사용하는 임시 메모리 영역으로 생각할 수 있는데, 컴파일 시에 할당될 영역의 크기가 결정됩니다.
  • 메모리의 높은 주소부터 낮은 주소 순으로 할당되며, 낭비하는 공간 없이 영역을 사용하게 됩니다.
  • 다만, Stack영역은 정해진 크기를 넘어 할당할 수 없습니다.
    • 운영체제마다 Stack 영역의 제한된 크기가 다릅니다.

 

Heap 영역

  • 앞에서 설명한 Stack과 달리, 프로그램이 실행되는 동안 사용자에 의해 동적으로 할당되고 해제됩니다. 그렇기 때문에 런타임(=프로그램이 실행되는 중)에 Heap 영역의 크기가 결정됩니다.
  • Stack 영역과는 반대로 낮은 주소에서 높은 주소 순으로 할당된다.
  • class 같은 참조 타입의 데이터가 저장되며, Java의 경우 가비지 콜렉터가, Swift의 경우 ARC가 관리해주게 됩니다.

 

Stack 영역과 Heap 영역

  • 사실 상 Stack 영역과 Heap 영역은 같은 공간을 사용.
  • 그래서 Stack 영역이 클 수록 Heap 영역이 작아지고, Heap 영역이 클 수록 Stack 영역이 작아짐 

 

  • Stack 영역은 높은 주소 ➡️ 낮은 주소 순으로, Heap 영역은 낮은 주소 ➡️ 높은 주소 순으로 할당되기 때문에 서로 자신의 영역이 상대의 영역을 침범하는 사태가 발생할 수 있다. (같은 공간을 사용하니까)
    • Stack Overflow : Stack이 Heap 영역 침범
    • Heap Overflow : Heap이 Stack 영역 침범

 

  • Stack 영역에서 말하는 할당이미 생성된 공간에 대해 포인터의 위치만 바꿔주는 단순한 CPU Instruction이기 때문에 할당 속도가 빠르다.
  • Heap 영역에서 말하는 할당은 요청되는 양과 현재 메모리 상황 등 다양한 요소를 고려해야 하기 때문에 더 많은 CPU Instruction이 필요하여 Stack 보다 할당 속도가 느리다.

 

Data 영역

  • 프로그램의 전역변수Static변수 등이 저장되는 영역으로, 프로그램 실행 시 전역변수와 Static변수는 메인 함수가 호출되기 전에 Data 영역에 할당됩니다.
  • 이렇게 할당된 데이터들은 로그램이 실행되고 끝날 때까지 메모리에 남아있습니다.
  • Data 영역은 BSS 영역과 Data 영역으로 구분지어 말할 수 있습니다.
    • BSS (Block Stated Symbol)
      • 초기화되지 않은 변수가 저장됩니다.
      • 원래 초기화된 데이터는 ROM의 Data 영역에 저장되는데, 아직 초기화되지 않은 데이터들까지 ROM에 저장되면 큰 사이즈의 ROM이 필요하기 때문에 BSS/DATA 영역을 나누어 저장합니다.
    • Data
      • 초기화가 이루어진 변수들이 저장됩니다.
      • 원래 Data 영역은 ROM에 위치하지만, 전역변수와 Static변수를 ROM에 저장하면 런타임시 변경된 값이 적용되지 않고 초기값만 가지게 되므로, RAM에 Data 영역을 복사하여 런타임시 변경되는 값을 저장할 수 있도록 합니다.
      • 따라서 프로그램 실행 중 접근/수정/변경이 가능합니다.

 

Code 영역

  • 사용자가 작성한 코드나, Read-Only 변수가 저장되는 영역으로, 컴파일 이후 기계어 형태로 저장됩니다.
  • 이렇게 저장된 데이터들은 프로그램이 실행되고 끝날 때까지 메모리에 남아있습니다.
  • Read-Only이기 때문에 수정이 불가합니다.

 

 

프로세스 / 스레드에서의 메모리

프로세스

프로세스는 메모리에 올라갈때 운영체제로부터 독립적인 시스템 자원을 할당받는다.

  • Code/Data/Stack/Heap의 유저 영역 메모리

 

 

중요 한것은 프로세스마다 독립적인 영역을 가지기 때문에 서로의 리소스에 접근할 수 없다.

 

스레드

프로세스와 달리 스레드는 일부 영역을 공유한다.

프로세스가 할당받은 메모리 영역 내에서 Stack 형식으로 할당된 메모리 영역은 따로 할당받고,

나머지 Code/Data/Heap 형식으로 할당된 메모리 영역을 공유한다.

 

 

스레드는 Code/Data/Heap 영역을 공유하기 때문에 이 영역에 어떤 스레드 하나에서 오류가 발생하면 같은 프로세스 내의 다른 스레드에도 영향을 준다.

 

Reference

https://beenii.tistory.com/111?category=833817 

 

메모리 구조를 알아보자.

메모리 구조 운영체제는 프로그램의 정보를 읽어 메인 메모리에 공간을 할당해 로드한다. 이 메모리의 구조를 알아봅시다 ^_^.. velog.io 데이터나 프로그램을 저장하는 저장 공간은 계층 구조를

beenii.tistory.com

https://jihyeong-ji99hy99.tistory.com/19

 

[리버싱] 왜 스택은 높은 주소에서 낮은 주소로 채워질까?

사실 메모리 구조 부분을 리버싱 분류로 넣어야 할까 고민했지만, 스택 프레임을 조사하면서 힙과 스택의 비교하기 위해서 조사했기에 다른 공부를 할 때 더 조사하더라도 현재는 리버싱으로

jihyeong-ji99hy99.tistory.com

 

728x90