운영체제

메모리 관리

은행털이 2024. 6. 3. 21:51

메모리 계층 구조

메모리는 컴퓨터 시스템 여러 곳에 계층적으로 존재한다

- CPU 레지스터 -> CPU 캐시 -> 메인 메모리 -> 보조기억장치

- 보조기억장치로 갈수록 가격이 저렴해지고 속도가 느려지며 용량이 증가

 

  레지스터 L1/L2 cache L3 cache 메인 메모리 보조기억장치
용도 몇 개의 명령과 데이터 저장 한 코어에서 실행하는 명령과 데이터 저장 멀티 코어들에 의해 공유되는 명령과 데이터 저장 실행중인 프로세스의 코드, 데이터와 입출력중인 파일 블록들 저장 파일, DB, 메모리에 적재된 코드, 데이터의 영구 저장
용량 byte 단위로 8~30개정도 존재
1KB 미만
KB단위 MB단위 GB단위 TB단위
타입   SRAM SRAM DRAM 마그네틱 필드나 플래시 메모리
속도 < 1ns < 5ns < 5ns < 50ns < 20ms
가격   고가 고가 보통 저가
휘발성 휘발성 휘발성 휘발성 휘발성 비휘발성

 

 

 

 

계층화 목적과 과정

- 메모리 액세스 시간을 줄여 빠른 프로그램의 실행을 위해 계층화 시도
- CPU의 성능 향상 -> 더 빠른 메모리의 필요성 -> 작지만 빠른 off-chip cache 적용 -> 더 빠른 액세스를 위해 on-chip cache를 적용 -> 멀티코어 시스템에 적합한 L1, L2, L3 cache 적용

-> off-chip cache란 CPU 외부에 존재하는 캐시메모리
-> on-chip cahce란 CPU 내부에 존재하는 캐시메모리로 물리적으로 거리가 가까우므로 off-chip cache보다 액세스가 빠름

 

 

 

 

계층화 성공 이유

매우 작은 용량의 캐시에 당장 실행할 코드의 일부분만 담아두어도 효과적일까?

 

효과적인 이유
-> 참조의 지역성 때문(Locality of reference)
    - 코드나 데이터, 자원 등이 아주 짧은 시간 내에 다시 사용되는 특성 때문에 효과적

-> 오버헤드의 정도
    - 캐시를 채우는데 생기는 오버헤드보다, 매우 빠른속도의 캐시메모리를 이용하는 이득이 더 큼

 

 

 

 

 

 

운영체제의 메모리 관리가 필요한 이유

  • 메모리는 공유자원
    - 여러 프로세스 사이에 메모리를 공유함
    - 한 프로세스가 메모리를 독점하면 당연히 다른 프로세스는 실행될 수 없으므로 메모리는 공유되어야 함
    - 각 프로세스에 물리 메모리를 할당해야함
  • 메모리는 보호되어야 함
    - 다른 프로세스로부터 보호받기 위해 프로세스별 독립된 메모리 공간을 보장해야 함
    - 사용자 코드로부터 커널 공간을 보호 받아야 함
  • 메모리 용량 한계 극복 필요
    - 설치된 물리 메모리보다 큰 프로세스를 실행하기위한 지원 필요
    - 여러 프로세스의 메모리 합이 설치된 메모리보다 큰 경우 한계 극복 필요
  • 메모리 효율성 증대 필요
    - 가능하면 많은 개수의 프로세스를 실행시키기 위해

 

 

 

 

물리주소와 논리주소

  • 물리주소(Physical Address)
    - 물리 메모리(RAM)에 매겨진, 하드웨어에 의해 고정된(Fixed) 메모리 주소
    - 0에서 시작하여 연속되는 주소 체계
    - 메모리는 시스템 주소 버스를 통해 물리 주소의 신호를 받음(32bit의 경우 2^32개의 주소 지정 가능)
  • 논리주소(Logical Address / Virtual Address)
    - 개발자나 프로세스가, 프로세스 내에서 사용하는 주소로 코드, 데이터, 힙, 스택과같은 영역에 대한 주소
    - 0에서 시작하여 연속되는 주소 체계, 물리주소와 달리 프로세스 내에서 매겨진 상대적 주소
    - 컴파일러와 링커에 의해 매겨진 주소
    - CPU 내에서 프로세스를 다루는 동안 사용하는 모든 주소는 논리주소
    - 사용자나 프로세스는 절대 물리주소를 알 수 없음
    - 논리주소와 물리주소 사이의 매핑 테이블은 프로세스마다 있음
  • MMU(Memory Management Unit)
    - 논리주소를 물리주소로 바꾸는 하드웨어적 장치
    - CPU가 발생시킨 논리주소는 MMU에 의해 물리주소로 바뀌어 물리메모리에 접근
    - 오늘날 MMU는 CPU에 내장되며 MMU덕분에 여러 프로세스가 하나의 물리메모리에 충돌없이 실행됨
    - 매핑테이블을 이용하여 주소 변환

 

 

 

 

컴파일과 논리주소

  • 컴파일러는 프로그램을 논리주소로 컴파일
    - 코드, 데이터, 힙, 스택을 0번지부터 시작하는 논리 주소에 할당
  • 응용프로그램 적재 시
    - 운영체제는 프로그램을 보조기억장치로부터 물리메모리의 적절한 위치(비어있는)에 적재
    - 논리주소와 물리주소의 매핑 테이블 생성
  • 응용프로그램 실행 시(프로세스)
    - CPU가 인지하는 모든 주소는 논리주소(CPU는 이미 컴파일된 명령들을 다루기 때문)
    - MMU는 CPU로부터 발생되는 논리주소를 물리주소로 변환(매핑 테이블 참조)
    - 함수가 호출될 때 사용되는 스택 주소 역시 논리 주소

 

ASLR(Address Space Layout Randomization)

- 해커들의 메모리 공격에 대한 대비책으로 오늘날 대부분의 운영체제가 사용
- 주소 공간을 랜덤으로 배치

  • 프로세스의 주소 공간 내에서 스택, 힙, 라이브러리 영역을 랜덤으로 배치(실행마다)
  • 실항할 때 마다 논리 주소가 바뀌게 하는 기법
  • 스택, 힙에 대해 적용하여 함수의 지역변수와 동적할당 받는 공간의 논리 주소가 실행시마다 바뀜
  • 코드영역이나 데이터영역, 전역변수의 논리주소는 바뀌지 않음

 

 

 

메모리 할당(Memory Allocation)

  • 운영체제가 새 프로세스를 실행시키거나(적재), 실행중인 프로세스가 메모리를 필요로 할 때(힙, 스택 영역 확장 등) 물리 메모리를 할당

 

메모리 할당 기법

  • 연속 메모리 할당 : 프로세스 별 한 덩어리의 메모리 할당
    - 고정 크기 할당
    -> 메모리를 고정크기의 파티션으로 미리 나누고, 프로세스 당 하나의 파티션을 할당
    -> 파티션의 크기는 모두 같거나 다를 수 있음
    -> 나눠진 파티션 중 프로세스 크기에 가장 가까운 파티션을 할당

    - 가변 크기 할당
    -> 메모리를 가변 크기의 파티션으로 나누고, 프로세스 당 하나의 파티션을 할당
    -> 고정 크기 할당과 다르게 미리 나누지는 않음
    -> 프로세스 크기나 요청에 따라 동적으로 할당


  • 분할 메모리 할당 : 프로세스에게 여러 덩어리의 메모리 할당
    -> 연속 메모리 할당은 프로세스 하나별로 연속된 메모리를 할당하므로 유연성이 부족함
    -> 할당된 프로세스 사이 사이에 빈 공간을 합치면 새 프로세스를 할당할 수 있음에도, 공간이 부족하여 할당하지 못함
    -> 이를 해결하기 위해 프로세스 별 연속된 1개의 덩어리가아닌, n개의 작게 쪼개진 덩어리들을 할당

    - 고정 크기 할당
    -> 고정 크기로 나눠진 메모리를 여러 개로 분산 할당 -> 페이징(Paging)기법
    -> 모든 프로세스를 page라고 불리는 고정 크기 단위로 분할, 물리 메모리의 frame에 적재

    - 가변 크기 할당
    -> 가변 크기로 나눠진 메모리를 여러 개로 분산 할당 -> 세그멘테이션(Segmentation)기법
    -> 코드, 데이터, 힙, 스택 등을 세그먼트로 나눠 적재
    -> 세그먼트들의 크기가 각기 달라 외부 단편화 초래 가능

 

 

 

 

 

연속 메모리 할당

연속 메모리 할당은 초기 운영체제에서 사용됨

  • 단일 프로세스 시스템
    - 한 프로세스가 전체 메모리를 독점하는 방식(MS-DOS)
  • 고정 크기 할당
    - IBM OS/360 MFT
    - 메모리 전체를 n개의 고정된 크기로 분할, 하나의 프로세스에 하나씩 할당
    - 수용 가능 프로세스는 n개로 고정
    - 메모리가 부족하면 프로세스는 큐에서 대기
  • 가변 크기 할당
    - IBM OS/360 MVT
    - 프로세스마다 프로세스 크기만큼의 연속 메모리 할당
    - 수용가능한 프로세스의 수는 크기에 따라 가변적
    - 메모리가 부족하면 프로세스는 큐에서 대기

-> 전부 가상메모리 기법은 지원하지 않음

 

 

 

 

 

단편화

- 프로세스에게 할당할 수 없는 작은 조각 메모리들이 생기는 현상, 이 조각 메모리를 홀(Hole)이라고 부름

  • 내부 단편화(Internal fragmentation)
    - 고정되어 할당된 메모리 내부에 사용할 수 없는 홀이 생기는 현상
    - 파티션보다 작은크기의 프로세스를 할당하는 경우, 파티션 내에 홀이 발생
    - IBM OS/360 MFT
  • 외부 단편화(External fragmentation)
    - 가변 크기로 할당된 메모리들 사이사이에서 사용할 수 없는 홀이 생기는 현상
    - 프로세스와 프로세스 사이의 홀이 새로 적재할 프로세스보다 작으면 할당할 수 없음
    - IBM OS/360 MVT

 

 

 

 

연속 메모리 할당 구현

  • 하드웨어의 지원
    - CPU에 담당 레지스터가 필요
    - base 레지스터 : 현재 실행중인 프로세스에게 할당된 물리메모리 시작 주소
    - limit 레지스터 : 현재 실행중인 프로세스에게 할당된 메모리의 크기
    - 주소 레지스터 : 현재 액세스하려는 메모리의 논리 주소
    - MMU 필요
  • 운영체제의 지원
    - 프로세스별 할당된 물리메모리 시작 주소와 할당된 메모리의 크기 정보를 저장, 관리
    - 비어있는 메모리 영역 관리
    - 새 프로세스를 스케줄링하여 실행할 때 마다, 물리 메모리 시작 주소와 할당된 메모리의 크기 정보를 CPU 내부 base레지스터와 limit 레지스터에 적재

 

연속 메모리 할당의 장단점

  • 장점
    - 논리주소를 물리주소로 바꾸는 과정이 단순, CPU의 메모리 액세스 속도가 빠름(나누어진 것이 아닌 하나의 덩어리이므로)
    - 운영체제가 관리할 정보량이 적어서 부담이 덜함
  • 단점
    - 메모리 할당의 유연성이 떨어짐. 작은 홀들을 합쳐 충분한 크기의 메모리가 있어도 연속된 메모리를 할당할 수 없는 상황 발생 -> 메모리 압축 기법으로 해결

 

 

홀 선택 알고리즘

- 운영체제는 메모리가 할당된 위치, 크기, 비어있는지 유무 등의 할당된 파티션에 관한 정보를 유지 관리
- 이 정보들을 포함한 리스트를 할당 리스트라고 함(Allocation list)

 

할당 요청에 관한 운영체제의 홀 선택 전략

  • 최초적합(First-Fit)
    - 홀 리스트를 검색하여 처음으로 만나는 할당 가능한 크기의 홀을 선택
    - 할당 속도는 빠르나, 단편화 발생 가능
  • 최적적합(Best-Fit)
    - 홀 리스트를 검색하여 할당 가능한 홀 중에서 가장 작은 홀을 선택
    - 크기별로 홀이 정리되어있지 않으면 전부 검색해야하므로 오버헤드가 큼
  • 최악적합(Worst-Fit)
    - 홀 리스트를 검색하여 할당 가능한 홀 중에서 가장 큰 홀을 선택
    - 크기별로 홀이 정리되어있지 않으면 전부 검색해야하므로 오버헤드가 큼
    - 거의 사용되지 않음

 

 

 

 

세그멘테이션

  • 세그멘트(Segment) : 프로그램을 구성하는 논리적 단위로 각각 의미와 용도를 가짐
    - 일반적인 세그먼트의 종류로 코드 세그멘트, 데이터 세그멘트, 힙 세그멘트, 스택 세그멘트가 있음
  • 세그멘테이션 기법
    - 프로세스를 논리 세그멘트로 나누고, 각 세그멘트를 물리 메모리(물리 세그멘트)에 할당하는 메모리관리 기법
  • 프로세스의 주소 공간
    - 프로세스의 주소공간은 여러 개의 논리 세그멘트들로 구성
    - 각 논리 세그멘트는 물리 세그멘트에 매핑
    - 프로세스를 논리 세그멘트로 나누는 과정은 컴파일러와 링커에 의해 이루어짐
    - 컴파일러와 링커는 응용프로그램과 라이브러리의 코드를 모아 코드 세그멘트를 구성, 전역변수를 모아 데이터 세그멘트 구성
    - 운영체제 로더는 실행 파일에 구성된 각 논리 세그멘트를 물리 세그멘트에 할당, 논리 세그멘트 적재
  • 논리 세그멘트와 물리 세그멘트의 매핑
    - 시스템 전체에 1개의 세그멘트 테이블을 두고 논리주소를 물리주소로 변환
  • 외부 단편화 발생 가능
    - 세그멘트들의 크기가 같지 않기 때문에, 세그멘트들 사이에 홀이 발생
    - 필요한 만큼만 할당하므로 내부 단편화는 발생하지 않음

 

 

 

세그멘테이션의 구현

  • 하드웨어의 지원
    - 논리 주소 구성 : [세그멘트 번호, 오프셋]
    - 오프셋 : 세그멘트 내의 상대 주소, 어떤 기준점으로 부터 얼마나 멀어져있는지를 나타내는 값(메모리 침범 방지)

    - CPU : 세그멘트 테이블의 시작 주소를 가리키는 레지스터 필요(Segment Table Base Register, STBR)
    - MMU 필요 : 논리 주소가 세그먼트 범위를 넘는지 판별(오프셋 이용), 논리주소를 물리주소로 변환(메모리 할당)
    - 세그멘트 테이블 : 메모리에 저장, 세그멘트별 시작 물리주소(base), 세그멘트 크기 정보 저장(limit)
  • 운영체제의 지원
    - 세그멘트의 동적 할당/반환 및 세그멘트 테이블 관리 기능 구현
    - 프로세스의 생성/소멸에 따라 동적으로 세그멘트 할당/반환
    - 물리 메모리에 할당된 세그멘트 테이블과 자유 공간에 대한 자료 유지
    - 컨텍스트 스위칭 때 CPU 레지스터에 적절한 값 로딩
  • 컴파일러, 링커, 로더의 지원
    - 사용자 프로그램을 세그멘트 기반으로 컴파일, 링킹, 로딩

 

 

 

 

 

'운영체제' 카테고리의 다른 글

페이징 메모리 관리  (0) 2024.06.04
교착 상태(Dead Lock)  (1) 2024.06.03
스레드 동기화  (1) 2024.06.03
CPU 스케줄링  (2) 2024.06.02