[8, 9주차] 메모리 관리

신은지·2021년 11월 7일
0

반효경 공룡 OS

목록 보기
8/8

메모리 : 주소를 통해 접근

메모리의 주소

  1. Logical address (=virtual address)
    : 프로세스마다 독립적으로 가지는 주소 공간
    : 각 프로세스마다 0번지부터 시작
    : CPU가 보는 주소

  2. Physical address
    :메모리에 실제 올라가는 위치

주소 바인딩
: 주소를 결정하는 것.
: Symbolic Address(플머가 바라보는 주소) -> Logical Address(CPU가 바라보는 주소) -> Physical address(물리적 주소)의 시점이 언제인가?


주소 바인딩

  1. Compile time binding
  • 물리적 메모리 주소가 컴파일 시 알려진다
  • 시작 위치 변경시 재컴파일
  • 컴파일러는 절대 코드를 생성 : 주소 변환 등 필요없고 그냥 그대로 쓰면 됨
  1. Load time binding
  • Loader의 책임하에 물리적 메모리 주소 부여
  • 컴파일러가 재배치가능코드를 생성한 경우 가능
  1. Execution time binding (=Run time binding)
  • 수행이 시작된 이후에도 프로세스의 메모리 상 위치를 옮길 수 있다
  • CPU가 주소를 참조할 때마다 binding을 점검한다 (address mapping table)
  • 하드웨어적 지원(MMU)이 필요

2와 3의 차이?

  • 2는 프로그램이 시작되는 시점에 물리적 메모리 주소 매겨지고 이후 바뀌지 X
  • 3은 프로그램이 실행되는 도중 물리적 메모리 주소가 바뀔 수 있는 것

CPU가 왜 논리적 주소를 보는가?
: CPU는 기계어를 실행하고, 기계어가 참고하는 주소는 논리적 주소이기 때문!


Memory-Management Unit (MMU)

  • MMU
    : logical address를 physical address로 매핑해주는 하드웨어 디바이스

  • MMU scheme
    : 사용자 프로세스가 CPU에서 수행되며 생성해내는 모든 주소값에 대해 base register(=relocation register)의 값을 더한다

  • user program
    : logical address만을 다루며, 실제 물리 주소를 볼 수도 없고 알 필요도 없다.

OS 및 사용자 프로세스 간의 메모리 보호를 위해 사용하는 레지스터

  • relocation register : 접근할 수 있는 물리적 메모리 주소의 최소값
  • limit register : 논리적 주소의 범위

Dynamic Loading

Loading : 메모리로 올리는 것

  • 프로세스 전체를 메모리에 미리 다 올리는 것이 아니라, 해당 루틴이 불려질 때 메모리에 load하는 것
    : memory utilization의 향상
    : OS의 특별 지원 없이 프로그램 자체에서 구현 가능

Overlays

  • 메모리에 프로세스 부분 중 실제 필요한 정보만을 올리는 것
    : 프로세스의 크기가 메모리보다 클 때 유용!
  • OS 지원 없이 사용자에 의해 구현
    : 작은 공간의 메모리를 사용하던 초창기 시스템에서 플머가 수작업으로 구현
    : 매우 복잡한 프로그래밍 필요

Swapping

  • Swapping
    : 프로세스를 일시적으로 메몰리에서 backing store로 쫓아내는 것 (디스크)

  • Backing store (=swap area)
    : 디스크
    : 많은 사용자의 프로세스 이미지를 담을 만큼 충분히 빠르고 큰 저장공간

  • Swap in / Swap out
    : 일반적으로 중기 스케줄러(swapper)에 의해 swap out 시킬 프로세스를 선정
    : priority-based CPU scheduling algorithm (우선순위 낮은 프로세스를 swapped out)
    : 컴파일 시간 혹은 로드 타임 바인딩에서는 원래 메모리 위치로의 swap in이 필요
    : 실행 시간 바인딩에서는 빈 메모리 영역 아무곳에나 올릴 수 있다
    : swap time은 대부분 transfer time (swap 양에 비례하는 시간)


Dynamic Linking

Linking
: 여러개의 코드와 데이터를 모아 로드&실행될 수 있는 한 개의 파일로 만드는 작업
: 프로그램은 컴파일 후 링킹이 되어야 실행될 수 있다

  • Linking을 실행 시간까지 미루는 기법
  1. Static linking (=static library)
    : 라이브러리가 프로그램의 실행 파일 코드에 포함된다
    : 실행 파일의 크기가 커진다
    : 동일 라이브러리를 각각의 프로세스가 메모리에 올린다 = 메모리 낭비!

  2. Dynamic linking
    : 라이브러가 실행 시 link된다
    : 라이브러리 호출 부분에 라이브러리 루틴의 위치를 찾기 위한 stub이라는 코드를 사용한다
    : 라이브러리가 이미 메모리에 있다면 -> 그 루틴 주소로 이동. 없다면 -> 디스크에서 읽는다
    : OS 도움이 필요


Allocation of Physical Memory

  • 메모리의 두 영역
    (1) OS 상주 영역 : 낮은 주소 영역
    (2) 사용자 프로세스 영역 : 높은 주소 영역

  • 사용자 프로세스 영역의 할당 방법
    (1) Contiguous allocation (연속 할당)
          : 각각의 프로세스가 메모리의 연속적인 공간에 적재되도록 하는 것
          : Fixed partition allocation, Variable partition allocation
    (2) Noncontiguous allocation (불연속 할당)
          : 하나의 프로세스가 메모리의 여러 영역에 분산되어 올라갈 수 있다
          : Paging, Segmentation, Paged Segmentation

연속 할당 방식의 종류

  1. 고정 분할 방식 (Fixed partition)
    : 물리적 메모리를 몇 개의 영구적 분할(partition)으로 나눈다
    : 분할의 크기가 모두 동일한 방식과 서로 다른 방식이 존재
    : 분할당 하나의 프로그램을 적재한다
    : 융통성 X - 동시 메모리에 로드되는 프로그램 수 고정 & 최대 수행 가능 프로그램 크기 제한
    : Internal & external fragmentation 발생

  2. 가변 분할 방식 (Variable partition)
    : 프로그램의 크기를 고려해서 할당
    : 분할의 크기, 개수가 동적으로 변한다
    : 기술적 관리 기법 필요
    : external fragmentation 발생

Hole
: 가용 메모리 공간
: 다양한 크기의 hole들이 메모리 여러 곳에 흩어져 있으며, 프로세스가 도착하면 수용 가능한 hole을 할당한다.
: OS는 할당 공간과 가용 공간(hole) 정보를 유지해야 한다.

Dynamic Storage-Allocation Problem
: 가변 분할 방식에서 size n인 요청을 만족하는 가장 적절한 Hole을 찾는 문제
1. First fit : Size가 n 이상인 것 중 최초로 찾아지는 hole에 할당
2. Best fit : Size > n인 가장 작은 hole 찾아서 할당
3. Worst fit : 가장 큰 hole에 할당

Compaction
: external fragmentation 문제르 해결하는 한 가지 방법
: 사용 중인 메모리 영역을 한 군데로 몰고, hole들을 다른 한 곳으로 몰아 큰 block을 생성한다.
: 비용은 많이 들지만, 최소한의 메모리 이동으로 compaction하는 방법 (어렵)
: 프로세스 주소가 실행 시간에 동적으로 재배치 가능한 경우에만 수행 가능


Paging

주소 변환 하더라도 페이지 사이의 오프셋은 동일!

  • 프로세스의 가상 메모리를 동일한 사이즈의 page 단위로 나눈다
    : 가상 메모리 내용이 page 단위로 noncontiguous하게 저장된다
    : 일부는 backing storage에, 일부는 physical memory에 저장된다

  • 방법

  1. physical memory를 동일한 크기의 frame으로 나눈다
  2. logical memory를 frame과 동일 크기의 page로 나눈다
  3. 모든 가용 frame들을 관리한다
  4. page table을 이용, logical address를 physical address로 변환한다
  5. external fragmentation은 발생하지 않지만, internal ffragmentation은 발생 가능

Implementation of Page Table

페이지 테이블에 비트 하나를 이용, frame number가 메모리에 올라갔는지 아닌지 (의미 있는지v 아닌지i)를 표시한다

  • Page Table은 메인 메모리에 상주한다
    : Page-tagle base register(PTBR)가 page table을 가리킨다
    : Page-tagle length register(PTLR)가 테이블 크기를 보관한다

  • 모든 메모리 접근 연산에는 2번의 메모리 접근이 필요하다
    : page table 접근에 1번, 실제 data/instruction 접근에 1번

  • 속도 향상을 위해 associative register 또는 translation look-aside bufffer(TLB)라 불리는 고속의 lookup hardware cache를 사용한다
    :

Effective Access Time
: TLB Hit ratio가 1에 가깝기 때문에, 메모리 접근 시간을 줄일 수 있다


Two-level Page Table

  • 현대 컴퓨터는 address space가 매우 큰 프로그램을 지원
    : 대부분의 프로그램이 주소 공간 중 지극히 일부만 사용 - page table 공간의 낭비 발생
    : page table 자체를 page로 구성하여 해결
    (사용하지 않는 주소 공간에 대한 outer page table의 엔트리 값은 NULL! )

  • Address-Translation Scheme
    : 2단계 페이징에서의 주소 변환 구조

Example


Multilevel Paging and Performance

  • Address space가 더 커지면 다단계 페이지 테이블이 필요
    : 각 단계의 페이지 테이블이 메모리에 존재하므로, logical address의 physical address 변환에 더 많은 메모리 접근이 필요하다!
    : TLB를 통해 메모리 접근 시간을 줄일 수 있다.

Memory Protection

Page Table의 각 entry마다 아래의 bit를 둔다

  1. Protection bit
    : page에 대한 접근 권한 (read/write/read-only)

  2. Valid-invalid bit

  • valid : 해당 주소의 frame에 그 프로세스를 구성하는 유효한 내용이 있음을 의미 (접근 허용)
  • invalid : 해당 주소의 frame에 유효한 내용이 없을을 의미 (접근 불허)

Inverted Page Table

  • page table이 매우 큰 이유 (=오버헤드)
    : 모든 프로세스 별로 논리 주소에 대응하는 모든 페이지에 대해 페이지 테이블 엔트리가 존재
    : 대응하는 페이지가 메모리에 있든 말든 간에 페이지 테이블에는 엔드리로 존재

  • Inverted Page table
    : page frame 하나당 페이지 테이블에 하나의 엔트리를 둔 것
    : 각 페이지 테이블 엔트리는 각각의 물리적 메모리의 페이지 프레임이 담고 있는 내용을 표시
    : 테이블 전체를 탐색해야하지만, associative register를 사용해서 해결할 수 있다.


Shared Page

  • Re-entrant Code (=재진입가능 코드 = Pure code)
    : read-only 설정으로 프로세스 간에 하나의 코드만 메모리에 올린다.
    : shared code는 모든 프로세스의 논리 주소 공간에서 동일한 위치에 존재!

  • private code and data
    : 각 프로세스들은 독자적으로 메모리에 올린다
    : private data는 logical address space의 아무곳에나 와도 무방


Segmentation

  • 프로그램은 의미 단위인 여러 개의 segment로 구성된다
    : 작게는 프로그램을 구성하는 함수 하나하나를 세그먼트로 정의
    : 크게는 프로그램 전체를 하나의 세그먼트로 정의
    : 일반적으로 code, data, stack 부분이 하나씩의 세그먼트로 정의된다
    : logical unit!

Architecture

  • Logical address의 구성
    : < Segment-number, offset >

  • Segment table
    : base - starting physical address of the segment
    : limit - length of the segment

    • Segment-table base register (STBR)
      : 물리적 메모리에서의 segment table의 위치

    • Segment-table length register (STLR)
      : 프로그램이 사용하는 segment의 수

  • Protection
    : 각 세그먼트 별로 protection bit 존재
    : (1) valid bit
    : (2) read/write/execution 권한 bit

  • Sharing

    : shared segment
    : same segment number
    : segment는 의미 단위라서 공유 & 보안에 있어 페이징보다 훨씬 효과적!

  • Allocation
    : first fit / best fit
    : external fragmenation 발생
    : segment의 길이가 동일하지 않다 = 가변 분할 방식에서와 동일한 문제점 발생


Segmentation with Paging

실제 프로그램에서 사용하는 방법

  • 세그먼트가 여러개의 페이지로 구성 (세그먼트 크기가 페이지 길이의 배수)
    : segment-table entry가 세그먼트의 base address를 가지는게 아니라, 세그먼트를 궝하는 page table의 base address를 가진다.
profile
호그와트 장학생

0개의 댓글