OS의 메모리 구조

dev hyeon·2023년 7월 22일
0
post-thumbnail

OS의 메모리 구조는 프로그램의 실행과 메모리 관리를 효율적으로 처리하기 위해 사용하는 것이기에 이를 알아보자.

우리가 작성한 코드는 어떠한 구조에 실행되고 있을까?

메모리의 전체적인 구조

OS에서 메모리는 어떻게 할당하는지 알아보자.

OS에서 메모리는 4개의 영역으로 나뉘며, 각 영역은 어떤 역할을 가지는지 정리해보자.

4개의 영역을 그림으로 그려보면,

이런식의 코드, 데이터, 힙, 스택 영역을 가지고 있다.

코드영역

코드 영역은 실행 가능한 프로그램의 코드(명령어)가 저장되는 영역이다. 이 영역은 프로그램의 명령어들이 메모리에 올라와 실제로 실행되는 부분들을 포함한다.

코드 영역은 프로그램의 기계어 명령어, 함수들의 몸체, 제어문, 상수 데이터 등이 저장되어 있고, 컴파일러나 인터프리터에 의해 기계어로 변환된 프로그램의 코드가가 이 영역에 위치하게 되는 영역이다.

일반적으로 이 코드 영역은 읽기 전용(Read-Only) 으로 설정되어 있기에 실행되는 동안에는 이 부분의 내용을 변경할 수 없다. 즉, 이러한 설정 덕분에 프로그램은 안정성과 보안을 가질 수 있다.

데이터 영역

데이터 영역은 프로그램의 전역 변수, 정적 변수, 초기화된 데이터 등을 저장하는 메모리 영역이다.

이 영역은 프로그램이 실행되는 동안 데이터들이 저장되는 공간이며, 읽기와 쓰기모두 가능하다.

💡 데이터 영역에 포함되는 데이터들 설명

  1. 전역 변수 (Global Variables): 프로그램의 어느 곳에서나 접근 가능한 변수들이 저장됩니다. 전역 변수들은 프로그램의 시작과 함께 생성되고 프로그램이 종료될 때까지 유지됩니다.
  2. 정적 변수 (Static Variables): 특정 함수나 블록에서만 접근 가능한 변수들로, 해당 함수나 블록이 처음 실행될 때 생성되며, 프로그램이 종료될 때까지 유지됩니다.
  3. 초기화된 데이터 (Initialized Data): 전역 변수나 정적 변수들 중에서 초기값을 명시적으로 지정한 데이터들이 저장됩니다. 예를 들어, int x = 42와 같이 초기값이 있는 변수들이 이 영역에 저장됩니다.

스택 영역

스택 영역은 함수의 호출과 관련된 지역 변수, 매개변수, 함수의 호출 정보등을 저장하는 메모리 영역이다.

스택은 데이터를 후입 선출(LIFO Last-In-First-Out) 방식으로 저장하고 관리하는 자료구조로, 함수 호출과 복귀를 지원하기 위해 사용한다.

💡 스택 영역에 포함되는 데이터들 설명

  1. 함수의 매개변수: 함수 호출 시 전달된 매개변수들이 스택에 저장됩니다.
  2. 지역 변수: 함수 내에서 선언된 지역 변수들이 스택에 할당되고 함수가 종료되면 스택에서 제거됩니다.
  3. 함수의 호출 정보: 함수가 호출될 때, 현재 실행 위치나 복귀 주소와 같은 정보들이 스택에 저장되어 함수가 종료되면 이 정보들을 이용하여 원래 호출된 위치로 돌아갈 수 있게 됩니다.

스택은 함수가 중첩되어 호출되는 경우에도 각각의 함수에 대해 별도의 프레임(Stack Frame)을 생성하여 관리 한다. Stack Frame은 각 함수가 실행될 때 함수와 관련된 데이터들을 저장하는 작은 메모리 블록으로 이해하면 된다.

스택은 메모리 주소가 자동으로 할당되며, 함수가 호출되면 해당 함수에 필요한 데이터를 스택에 할당하고 함수가 종료되면 스택에서 자동으로 제거해줍니다. 그렇기에 함수 호출과 복귀가 효율적으로 이루어질 수 있다.

힙 영역

힙 영역은 프로그램의 동적으로 할당된 메모리를 관리하는 영역이다. 힙은 프로그램이 실행 중에 필요한 메모리를 동적으로 할당하고 해제하는 데 사용되며 이를 통해 프로그램이 런타임 중에 유연하게 메모리를 사용할 수 있게 된다. 또한, 힙 영역은 대게 '낮은 주소에서 높은 주소로 할당 된다.'

💡 힙 영역의 특징

  1. 동적 메모리 할당: 힙 영역은 프로그래머가 필요에 따라 메모리를 동적으로 할당할 수 있는 기능을 제공합니다. C/C++의 malloc(), calloc(), C++의 new 같은 동적 할당 함수를 사용하여 힙 영역에서 메모리를 할당할 수 있습니다.
  2. 크기 조정: 힙 영역에서 할당된 메모리는 크기를 조정하는 것이 가능합니다. 동적 할당된 메모리를 더 필요로 할 때 크기를 늘리거나, 더 이상 사용하지 않을 때 크기를 줄일 수 있습니다.
  3. 수동 해제: 힙 영역에서 할당된 메모리는 사용이 끝나면 수동으로 해제해주어야 합니다. 메모리 누수를 방지하기 위해 할당된 메모리를 더 이상 사용하지 않을 때, 프로그래머가 해당 메모리를 명시적으로 해제해주어야 합니다. C/C++에서는 free(), C++에서는 delete 와 같은 방법으로 동적으로 할당된 메모리를 해제할 수 있다.

힙 영역은 데이터 영역과 다르게 크기가 동적으로 변경될 수 있으며, 사용자가 직접 메모리 할당과 해제를 관리해야 한다.(java나 python와 같은 언어들은 가비지 컬렉터가 자동으로 메모리를 관리해 준다.) 이러한 특징 때문에 힙은 복잡한 데이터 구조나 동적으로 크기가 변하는 데이터를 저장하기 위해 사용되며, 메모리를 효율적으로 사용할 수 있도록 해준다. 하지만 동적 메모리 할당과 해제를 올바르게 다루지 않는다면 메모리 누수와 같은 문제가 발생할 수 있다.

Stack Overflow & Heap Overflow

전체적인 메모리 구조를 설명할 때, 힙 영역과 스택 영역은 위 그림 에서 화살표 처럼 서로 영향을 줄 수 있다.

이유는, 사실 힙 영역과 스택 영역은 위 그림 처럼 같은 공간을 공유하기 때문이다. 같은 공간을 공유하기 때문에 각각의 영역이 overflow 문제를 발생시킬 수 있다. 왜냐면, Heap은 Low address(그림 상 위) 주소값부터 (그림상 아래)로 주소값을 채우고, Stack은 High address(그림상 아래)주소값 부터 (그림상 위)로 주소값을 채우기 때문에 두 메모리 영역의 주소가 겹쳐 지는 순간이 있을 수 있기 때문이다.

Stack Overflow

Stack영역이 Heap의 영역을 침범하는 경우 발생.

Heap Overflow

Heap영역이 Stack의 영역을 침범하는 경우 발생.

profile
정리 블로그

0개의 댓글