프로세스 메모리

cutiepazzipozzi·2023년 8월 10일
1

Challenge

목록 보기
3/7
post-thumbnail

프로그램 실행

= 실행 파일이 메모리에 적재
= 프로그램이 CPU를 할당받아 명령을 수행中

프로세스 메모리 주소

메모리 1칸 = 1 byte
-> 32bit OS = 4byte길이의 주소를 가짐

프로세스 메모리 구조

디스크에서 메모리를 불러오는 로딩 과정 중에 프로세서들이 프로세스를 생성하고, 이는 프로세스가 갖는 메모리 구조가 결정됨을 의미한다. 이 CPU에서 프로세스를 하나씩 만들 때마다 아래 4가지로 구성된 메모리 모델이 생성된다.

잠깐! 메모리 구조를 왜 알아야 할까?

한정된 자원 안에서 우리는 효율적으로 프로그램을 실행해야 하기 때문!
(메모리를 잘 다뤄야 메모리 낭비를 막을 수 있음)

메모리 주소 공간을 왜 나눌까?

(결론적으로는 왜 알아야 하는지랑 같은 말 인듯?)
= 데이터를 공유하여 메모리 사용량을 줄이기 위해
(ex. Code 영역 -> 같은 프로그램이라면 같은 내용을 가지므로 따로 관리)

1. 코드 영역 (=텍스트)

= 실행할 프로그램 코드가 저장되는 영역

  • 따라서 코드가 저장됨
    (컴파일 타임에 결정되어 코드를 수정할 수 없음 - Read-Only)
  • 코드 실행에 구성되는 명령문이 저장
    (CPU에서 수행할 수 있는 기계어 명령문)

2. 데이터 영역

= 프로그램의 전역/정적(static) 변수가 저장되는 영역

  • 프로그램의 시작과 함께 할당되고, 프로그램의 종료와 함께 소멸된다.
  • BSS (초기화되지 않은 변수 0으로 초기화하여 저장) 영역,
    Data (0이 아닌 다른 값으로 할당된 변수 저장) 영역으로 나뉜다.
    (초기화되지 않은 데이터가 ROM에 저장되면 정말 큰 size가 필요하므로 초기화되지 않은 데이터는 RAM에 저장한다)

3. 힙 영역

= 사용자가 직접 관리하는 (동적) 메모리 영역
-> 프로그램이 사용할 데이터를 저장

  • 동적으로 메모리를 할당/해제 할 수 있다
    (따라서 런타임 시 영역의 크기?가 결정됨 / malloc, free)
  • (사진을 보면 알겠쥐만) 낮->높은 주소로 할당

4. 스택 영역

= 지역/매개 변수가 저장되는 영역
-> 호출된 함수의 수행이 끝나면, 복구할 주소 & 데이터 임시 저장 (=Stack Frame)
** 데이터 ex. 지역변수, 매개변수, 리턴 값

  • 함수의 호출과 함께 할당되고, 함수의 호출이 끝나면 소멸
  • 스택처럼 후입선출(LIFO)의 방식을 따르고, 힙과 반대로 높->낮은 주소로 할당
    (갑자기 글을 쓰다가 왜 높은 주소부터 채워지는지 생각해봤는데 얼마나 필요한지 미리 예측하기 힘들어 MAX 주소부터 채우는게 맞는 것 같다 /
    오 또한 자료구조에서의 스택 방식을 사용해서 높->낮은 주소 방향으로 할당된다고도 하네용)
  • 컴파일 시에 크기 결정

Heap과 Stack

Overflow

두 영역은 (내 생각이지만) 명확히 구분되어있진 않은 것 같다. 그래서 각각 overflow가 발생하는 이유도 heap은 stack의 영역을 침범해서, stack은 heap의 영역을 침범해서이다.

++ 스택 오버플로우는 예상된 상황에서의 에러라기 보다는, 스택 포인터가 스택 경계를 넘어갈때(호출 스택이 제한된 양 이상의 주소 공간을 사용하려 할 때) 발생한다.

할당

Stack에서의 '할당'은, 크기가 정해져 있으므로 이미 생성된 스택 포인터의 위치만 바꿔주는 의미를 갖는다. 그러나 Heap에서의 '할당'은 메모리가 free된 fragment들이 존재하기 때문에 다양한 상황을 고려한 연산이 필요하다.

Heap의 메모리 관리

= 사실 Garbage Collector 동작 내용에 관해 얘기해보고자 한다.

정말정말 간단히 말하면 가리키는 포인터가 없는 힙의 영역을 Garbage Collector가 비워준다.
=> 힙 영역은 매우 넓기 때문에, 참조 변수(객체의 주솟값)가 사라지면 길 잃은 미아와 다를 바가 없어진다. 이런 객체는 힙의 메모리 공간이 꽉 차게 되면 Garbage Collection에 의해 소멸된다.

Garbage Collector는 New, Old Space로 나뉘고 New Space는 To/From 2가지 영역으로 구분된다. Old Space는 New Space(새로운 객체가 들어가는 곳)에서 참조가 2번 이상 일어난 객체를 저장한다. To/From space는 하나의 공간이 꽉 찼다면 참조 당한 객체만 빼내어 다른 공간으로 옮겨준다. (옮겨지지 못한 객체들은 참조가 없기 때문에 GC에 의해 소멸)

Heap Fragmentation

사용자가 힙 메모리를 할당받을 때, 관리자는 연속된 공간을 할당한다. 그러나 메모리들의 해제 시점은 순차적이지 않기 때문에 할당할 수 있는 여유 공간들이 파편화되는 현상이 발생한다. 이를 Heap Fragmentation이라 부른다.

이를 해결하기 위해 Free List 방식을 고안하였다.
이는 Linked List와 비슷한 자료 구조 형태이다. 메모리에 할당 되지 않은 영역을 연결 리스트로 연결시킨다. (free된 영역을 연결 리스트에!)

  • 해제 : 빈칸 목록에 연결
  • 할당: 빈칸 목록의 가장 끝 영역을 제거하고 데이터를 할당

Heap Chunk도 있다고 하는데 아직은 정확히 모르겠다.
** Chunk = malloc()의 호출로 할당받는 영역 + header를 포함한 영역

참고

프로세스 메모리 구조
내 깃블로그
메모리 구조2

profile
노션에서 자라는 중 (●'◡'●)

0개의 댓글