나를 기록하다
article thumbnail
반응형

메모리 관리의 개요

폰 노이만 구조에서 메모리는 유일한 작업 공간이며 모든 프로그램은 메모리에 올라와야 실행할 수 있다. 모든 프로그램은 하드디스크나 SSD와 같은 보조 저장장치에 보관되어 있다. 프로그램이 실행되어 프로세스가 된다는 것은 저장장치에 있던 프로그램이 메모리로 올라온다는 것이다.

 

메모리 이해하기

  • 메모리의 구조: 1바이트(B)의 크기로 나뉨
  • 1B로 나뉜 각 영역은 주소(address)로 구분, 보통 0번지부터 시작
  • CPU는 메모리에 있는 데이터를 가져오거나 작업 결과를 메모리에 저장하기 위해 주소 사용
  • 운영체제도 프로그램이므로 메모리에 올라와야 실행 가능
    → 전원 버튼 누르면 부팅이 이뤄지고 이때 하드디스크에 저장된 운영체제가 메모리에 올라감. 부팅이 끝나면 여러 응용 프로그램이 메모리에서 작업 가능
  • 메모리는 CPU 입장에서는 느린 장치 → 속도차 극복을 위해 CPU 안에 캐시를 만들어두고 메모리의 일정 부분을 미리 가져와 작업 또는 하드디스크나 SSD 같은 저장장치를 메인메모리의 보조 저장장치로 활용

 

메모리에 있는 데이터를 CPU로 가져오는 과정
1. 접근하려는 메모리 주소를 MAR에 넣으면 해당 주소가 주소 버스를 통해 메모리에 전달
2. 메모리에서는 해당 주소의 값을 데이터 버스를 통해 MBR로 보냄
3. MBR에 있는 데이터가 레지스터로 옮겨지면 메모리 접근 작업이 끝남
*FSB의 속도를 고려하면 CPU가 메모리에 접근하는 작업은 10클록 이상

 

메모리 관리의 이중성

  • 복잡한 메모리 관리는 메모리 관리 시스템(MMS; Memory Management System)이 담당
  • 프로세스 입장에서는 메모리를 독차지하려 하고, 메모리 관리자 입장에서는 관리를 효율적으로 하고 싶어 하는데 이를 메모리 관리의 이중성이라 함
  • 메모리 관리의 이중성을 달리 표현하면 프로세스 입장에서 작업의 편리함과 관리자 입장에서 관리의 편리함이 충돌하는 것

 

소스코드의 번역과 실행

소스코드의 번역 방식

  • 컴파일러: 소스코드를 컴퓨터가 실행할 수 있는 기계어로 번역한 후 한꺼번에 실행 ex) C, Java
  • 인터프리터: 소스코드를 한 행씩 번역하여 실행 ex) Javascript, Python

컴파일러 방식

  • 오류 발견 - 심벌 테이블(symbol table)
    • 오류를 찾기 위해 사용
    • 변수 선언부에 명시한 각 변수의 이름과 종류를 모아놓은 테이블
    • 선언하지 않은 변수의 사용 여부, 변수에 다른 종류의 데이터 저장 여부 확인 가능
  •  
  • 소스코드 최적화
    • 사용하지 않는 변수를 삭제하면 더욱 간결해져 실행 속도 증가
  • 컴파일러는 실행 전 소스코드를 점검하여 오류를 수정하고 필요 없는 부분을 정리하여 최적화된 실행 파일 생성
  • 인터프리터는 한 행씩 위에서부터 아래로 실행되기 때문에 같은 일을 반복하는 경우나 필요 없는 변수를 확인할 수 없음

컴파일러의 컴파일 과정

컴파일 과정

 

메모리 관리 작업

메모리 가져오기

  • 실행할 프로세스와 데이터를 메모리로 가져오는 작업
  • 메모리가 충분하지 않다면 데이터의 일부만 먼저 가져와 실행하고 필요할 때마다 수시로 가져와 실행할 수도 있음

메모리 배치

  • 가져온 프로세스와 데이터를 메모리의 어떤 부분에 올려놓을지 결정하는 작업
  • 메모리를 같은 크기로 자르는 것을 페이징(paging), 프로세스의 크기에 맞게 자르는 것을 세그먼테이션(segmentation)이라 함

메모리 재배치

  • 꽉 찬 메모리에 새로운 프로세스를 가져오기 위해 오래된 프로세스를 내보내는 작업
  • 앞으로 사용하지 않을 프로세스를 찾아서 내보내는 알고리즘을 교체 알고리즘(replacement algorithm)이라 함

메모리 주소

메모리에 접근할 때는 주소를 이용하는데 메모리 주소는 물리 주소와 논리 주소로 나뉜다.

32bit CPU와 64bit CPU의 차이

  • CPU를 나타낼 때의 비트는 CPU가 한 번에 다룰 수 있는 데이터의 최대 크기를 의미함
  • 32bit CPU는 한 번에 다룰 수 있는 데이터의 크기가 32bit, 64bit CPU는 64bit
  • 물리 공간: 메모리의 주소 공간, 하드웨어 입장에서 바라본 주소 공간으로 컴퓨터마다 크기가 다름
  • 논리 주소 공간: 사용자 입장에서 바라본 주소 공간

 

논리 주소와 물리 주소

메모리 영역의 구분

  • 메모리 관리자는 메모리를 운영체제 영역과 사용자 영역으로 나누어 관리
  • 운영체제는 시스템을 관리하는 중요한 역할을 하기 때문에 사용자가 운영체제를 침범하지 못하도록 분리해서 관리
  • 그림에서 운영체제가 0~359번지 사용, 사용자가 360 ~ 999번지 사용
  • 사용자 영역이 운영체제 영역으로 침범하는 것을 막기 위해 메모리 관리자는 사용자가 작업을 요청할 때마다 경계 레지스터의 값을 벗어나는지 검사하고, 만약 경계 레지스터를 벗어나는 작업을 요청하는 프로세스가 있으면 그 프로세스를 종료함

운영체제와 경계 레지스터

논리 주소와 물리 주소의 변환

문자형(char) 변수 alp를 선언하고 해당 변수에 대문자 A를 저장하는 경우

다음 코드가 실행되면 메모리의 어딘가에 문자 A가 저장됨. 그 주소를 40번지라 하자.

char alp = 'A';

1. char alp = 'A'의 코드가 컴파일되어 실행 파일이 만들어짐

2. 해당 실행 파일에 A를 넣는 기계어 코드 존재

3. 해당 코드가 실행되면 프로세스가 메모리(컴퓨터 내에 물리적으로 설치된 메인 메모리)에 올라옴

4. 물리 메모리도 0번지부터 시작하는 주소를 가지고 있음

5. 실행 파일 40번지의 A가 들어간다고 해서 실제로 물리 메모리의 40번지에 A가 들어가는 것은 아님

6. 실행을 위해 프로세스가 메모리에 올라오면 이 메모리는 빈 공간에 배치
(빈 공간의 시작 주소는 물리 메모리 주소 100번지일 수도 있고 300번지 일수도 있음)

7. 물리 메모리의 360번지부터 프로세스가 사용한다고 가정할 때 40번지는 물리 메모리의 주소 400번지가 됨

  • 400번지는 물리 주소 → 메모리의 입장에서 바라본 주소로 MAR가 사용하는 주소, 컴퓨터에 꽂힌 램 메모리의 실제 주소
  • 40번지는 논리 주소 → 시작점을 0으로 놓았을 때 40번지의 위치에 있는 주소, 사용자 프로세스 입장에서 바라본 주소

절대 주소(물리 주소) / 상대 주소(논리 주소)

8. 프로그램이 실행될 때마다 시작하는 물리 주소는 매번 바뀜 → 논리 주소와 물리 주소 사이에 차이 발생

  • 논리 주소 공간 : 항상 0번지부터 시작하며 컴퓨터가 허용하는 최대의 주소 크기를 가짐. 컴파일러는 논리 주소 공간의 0번지부터 변수들을 배치
  • 물리 주소 공간 : 0번지부터 시작하지만 최대 주소 크기는 컴퓨터에 설치된 메모리 크기에 따라 달라짐. 컴퓨터에 실제로 설치된 메모리의 크기가 마지막 주소가 됨

9. 논리 주소로 이루어진 프로세스를 실행하려면 이를 물리 주소로 변환하는 작업 필요 → 메모리 관리 유닛(MMU) 담당

  • 메모리 관리 유닛 : CPU 안에 존재, 프로세스가 논리 주소에 접근할 때마다 이를 물리 주소로 변환하는 작

논리 주소 → 물리 주소 변환

  • 변환 과정
    1. 사용자 프로세스가 논리 주소 40번지에 있는 데이터 요청
    2. CPU는 MMU에 40번지에 있는 내용을 가져오라고 명령
    3. MMU는 재배치 레지스터를 사용하여 메모리 400번지에 저장된 데이터를 가져옴

10. 재배치 레지스터를 사용하여 논리 주소를 물리 주소로 변환하기 때문에 메모리가 항상 0번지부터 시작하는 연속된 작업 공간으로 보임. 운영체제 영역이 바뀌어 사용자 영역이 500번지부터 시작된다면 재배치 레지스터에 500을 넣으면 된다.

 

단일 프로그래밍 환경의 메모리 할당

메모리 오버레이

  • 프로그램의 크기가 실제 메모리(물리 메모리)보다 클 때 전체 프로그램을 메모리에 가져오는 대신 적당한 크기로 잘라서 가져오는 기법
  • 하나의 메모리에 여러 프로그램을 겹겹이 쌓아놓고 실행하는 것
  • 필요한 모듈만 올려놓고 나머지는 필요할 때마다 메모리에 가져와 사용
  • 메모리 오버레이에서 어떤 모듈을 가져오거나 내보낼지는 CPU 레지스터 중 하나인 프로그램 카운터(PC)가 결정

메모리 오버레이의 작동 방식

메모리 오버레이의 중요한 의미
1. 한정된 메모리에서 메모리보다 큰 프로그램 실행 가능
2. 프로그램 전체가 아니라 일부만 메모리에 올라와도 실행 가능

 

스왑

  • 메모리가 모자라서 쫓겨난 프로세스를 저장장치의 특별한 공간에 모아두는데 이러한 영역을 스왑 영역이라 부르고 메모리 관리자가 관리
  • 스왑인(swap in) : 스왑 영역에서 메모리로 데이터를 가져오는 작업
  • 스왑아웃(swap out): 메모리에서 스왑 영역으로 데이터를 내보내는 작

스왑인 & 스왑아웃


다중 프로그래밍 환경의 메모리 할당

메모리 분할 방식

  • 가변 분할 방식: 프로세스의 크기에 따라 메모리를 나눔
  • 고정 분할 방식: 프로세스의 크기와 상관없이 메모리를 같은 크기로 나눔

메모리 분할 방식의 구현과 장단점

메모리 분할 방식의 구현

  • 가변 분할 방식
    • 프로세스 크기에 따라 메모리가 분할되며 한 프로세스가 연속된 공간에 배치되기 때문에 연속 메모리 할당이라고 함
    • 장점: 하나의 프로세스를 연속된 공간에 배치
    • 단점: 빈 공간을 하나로 합치기 위한 부가적인 작업이 필요하기 때문에 메모리 관리가 복잡함
  • 고정 분할 방식
    • 프로세스 크기와 상관없이 같은 크기로 메모리가 분할되며, 큰 프로세스가 메모리에 올라오면 여러 조각으로 나뉘어 배치
    • 한 프로세스가 분산되어 배치되기 때문에 비연속 메모리 할당이라고 함
    • 장점: 메모리 관리가 수월
    • 단점: 일정하게 나누어진 공간보다 작은 프로세스가 올라올 경우 메모리 낭비 발생

 

가변 분할 방식의 메모리 관리

가변 분할 방식의 특징

  • 가변 분할 방식은 프로세스의 크기에 맞춰 메모리를 할당하는 방법으로 세그먼테이션 메모리 관리 기법이라고 함
  • 프로세스를 하나의 연속된 주소로 다룬다는 장점
  • 빈 영역이 있어도 서로 떨어져 있으면 프로세스를 배정하지 못하는 문제 발생
    → 이로 인해 작은 조각들이 발생하는 현상을 단편화라고 함
    → 가변 분할 방식에서 발생하는 단편화는 조각이 프로세스의 바깥쪽에 위치하기 때문에 외부 단편화라고 함

가변 분할 방식과 외부 단편화

  • 외부 단편화로 인한 문제 해결을 위해 메모리 배치 방식이나 조각 모음 사용
  • 메모리 배치 방식: 작은 조각이 발생하지 않도록 프로세스 배치
  • 조각 모음: 조각이 발생했을 때 작은 조각들을 모아서 하나의 큰 덩어리로 만드는 작업
  • 메모리 배치 방식은 선처리, 조각 모음은 후처리

메모리 배치 방식

  1. 최초 배치
    • 단편화를 고려 x
    • 프로세스를 메모리의 빈 공간에 배치할 때 적재 가능한 공간 중 첫 번째로 발견한 공간에 프로세스를 배치하는 방법
  2. 최적 배치
    • 메모리의 빈 공간을 모두 확인한 후 크기가 가장 비슷한 곳에 프로세스를 배치
  3. 최악 배치
    • 빈 공간을 모두 확인한 후 가장 큰 공간에 프로세스를 배치하는 것, 최적 배치와 정 반대

메모리 배치 방식 비교

조각 모음

  • 작은 프로세스가 작업을 마치고 메모리에서 나가면 그 공간이 조각으로 남아 쓸모없어질 가능성이 큼
  • 단편화 발생 시 이미 배치도니 프로세스를 옆으로 옮겨 빈 공간들을 하나의 큰 덩어리로 만들어야 함
  • 이 작업이 바로 조각 모음
  • 서로 떨어져 있는 여러 개의 빈 공간을 합치는 작업, 메모리 통합이라 부르기도 함

조각 모음

  • 조각 모음 순서
    1. 조각 모음을 하기 위해 이동할 프로세스의 동작을 멈춤
    2. 프로세스를 적당한 위치로 이동. 프로세스가 원래의 위치에서 이동하기 때문에 프로세스의 논리 주소 값을 바꿈
    3. 앞의 1, 2 작업을 다 마친 후 프로세스를 다시 시작

 

고정 분할 방식의 메모리 관리

  • 고정 분할 방식을 사용하여 물리 메모리를 나누는 방식 → 페이징 메모리 관리 기법
  • 가변 분할 방식과 달리 프로세스의 크기에 상관없이 메모리를 같은 크기로 나누기 때문에 관리하기 편리함
  • 현대의 메모리 관리는 페이징을 기본으로 함

고정 분할 방식의 프로세스 배치

  • 단점: 일정하게 나뉜 메모리의 크기보다 작은 프로세스가 배치도리 경우 낭비되는 공간 생김
    → 이 경우 일정한 크기로 나뉜 파티션 안쪽으로 작은 조각 발생
    → 이처럼 각 메모리 조각에 프로세스를 배치하고 공간이 남는 것을 내부 단편화라고 함

가변 분할 방식과 고정 분할 방식의 비교

비교

버디 시스템

  • 외부 단편화를 완화하는 방법
  • 작동 방식
    1. 프로세스의 크기에 맞게 메모리를 1/2로 자르고 프로세스를 메모리에 배치
    2. 나뉜 메모리의 각 구역에는 프로세스가 1개만 들어감
    3. 프로세스가 종료되면 주변의 빈 조각과 합쳐서 하나의 큰 덩어리를 만듦
  • 가변 분할 방식과 고정 분할 방식의 특징을 모두 가짐
  • 가변 분할 방식처럼 메모리가 프로세스 크기대로 나뉨
  • 고정 분할 방식처럼 하나의 구역에 다른 프로세스가 들어갈 수 없고, 메모리의 한 구역 내부에 조각이 생겨 내부 단편화가 발생
  • 효율적인 공간 관리 측면에서 보면 고정 분할 방식과 버디 시스템은 비슷한 수준이나 메모리 고나리 측면에서 공간을 1/2로 나누어가며 메모리르 배분하는 버디 시스템보다 모든 공간을 똑같은 크기로 나누는 고정 분할 방식이 단순하기 때문에 버디 시스템보다 고정 분할 방식을 많이 사용함
반응형
profile

나를 기록하다

@prao

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...