7장, 메모리 관리
메모리는 주소를 통해 접근하는데, 메모리 주소는 이진수로 매겨진다. 컴퓨터는 바이트(byte) 단위로 메모리 주소를 부여한다. 메모리 주소는 계층적으로 관리하는데, 보통 4KB(12비트) 단위로 묶어 페이지(page)를 만들어 사용한다. 프로세스는 실행을 위해 메모리에 적재될 때 프로세스를 위한 독자적인 주소 공간이 형성된다. 이 주소를 논리적 주소(logical address) 혹은 가상 주소(virtual address)라고 한다. 각 프로세스에 독립적으로 할당된 논리적 주소는, 0번지부터 시작한다. 물리적 주소(physical address)는 물리적 메모리에 실제로 올라가는 위치를 말한다. 보통 물리적 메모리의 낮은 주소 영역에는 운영체제가, 높은 주소 영역에는 사용자 프로세스들이 올라간다. 논리적 주소를 통해 메모리를 참조하게 되면, 해당 논리적 주소가 물리적 메모리의 어느 위치에 매핑되는지 확인해야 한다.
주소 바인딩 ?
논리적 주소를 물리적 주소로 연결시켜주는 작업
- 컴파일 타임 바인딩(compile time binding)
프로그램을 컴파일할 때 물리적 메모리 주소가 결정되는 방식
절대 주소로 적재된다는 뜻으로 절대 코드(absolute code)를 생성하는 바인딩 방식이라고 함
위치를 변경하고 싶을 때마다 컴파일을 다시 해야 함. - 로드 타임 바인딩(load time binding)
프로그램이 시작될 때에 물리적 메모리 주소가 결정되는 방식
로더(loader, 사용자 프로그램을 메모리에 적재시키는 프로그램)의 책임 하에 메모리 주소가 부여되며, 프로그램이 종료될 때까지 물리적 위치가 고정된다
컴파일러가 재배치 가능 코드(relocatable code)를 생성한 경우에 가능한 방식 - 실행시간 바인딩(execution time binding / run time binding)
프로그램이 실행을 시작한 후에도 물리적 위치가 변경될 수 있는 방식
주소 매핑 테이블(address mapping table)을 이용해 바인딩을 점검한다
기준 레지스터(base register)와 한계 레지스터(limit register) 및 MMU(Memory Management Unit)라는 하드웨어적인 지원 필요
MMU 기법(MMU scheme)
(프로그램의 주소 공간이 물리적 메모리의 한 장소에 연속적으로 적재되는 것으로 가정한다)
논리적 주소 값에 기준 레지스터 값을 더하여 물리적 주소 값을 얻어낸다. 그때 논리적 주소 값이 한계 레지스터의 값보다 크다면, 트랩을 발생시켜 해당 프로세스를 강제 종료시킨다.
▶기준 레지스터 / 재배치 레지스터(relocation register)는 프로세스의 물리적 메모리 시작 주소를 가지고 있다.
▶한계 레지스터는 프로세스가 자신의 주소 공간을 넘어서는 메모리를 참조하지 않도록 프로세스의 크기를 담고 있다.
동적 로딩(dynamic loading)
프로세스의 주소 공간 전체를 메모리에 다 올려놓는 것이 아니라, 필요한 부분만을 메모리에 적재하는 방식
다중 프로그래밍 환경에서, 메모리 사용의 효율성을 높이기 위해 사용하는 방법이며, 프로그램 자체에서 구현하거나, 운영체제가 라이브러리를 통해 지원할 수 있다
▶연결(Linking)? 프로그래머가 작성한 소스코드를 컴파일하여 생성된 목적 파일(object file)과 이미 컴파일된 라이브러리 파일(library file)들을 묶어 하나의 실행파일을 생성하는 과정
동적 연결(dynamic linking)
컴파일을 통해 생성된 목적 파일과 라이브러리 파일 사이의 연결을 프로그램의 실행 시점까지 지연시키는 기법
↔정적 연결(static linking) : 소스 코드와 라이브러리 코드를 모두 합쳐 실행파일 생성한다. 동일한 라이브러리를 각 프로세스가 모두 적재하게 되면서, 메모리가 낭비된다.
동적 연결에서는 스텁(stub)이라는 작은 코드를 두어 라이브러리가 메모리 상에 이미 존재하는 지를 확인하여 처리한다. 운영체제의 지원이 필요한 기법이다.
중첩(overlays)
프로세스의 주소 공간을 분할해 실제 필요한 부분만 메모리에 적재하는 기법
동적 로딩과 유사하지만, 동적 로딩은 여러 개의 프로세스를 메모리에 올리기 위한 방법이라면 중첩은 메모리 공간보다 큰 프로세스를 실행하기 위한 방법이다. 프로그래머에 의해 구현되어야 해서 수작업 중첩(manual overlays)라고 불린다.
스와핑(swapping)
메모리에 올라온 프로세스의 주소 공간 전체를 디스크의 스왑 영역(swap area)에 일시적으로 내려놓는 것
▶스왑 영역 : 백킹 스토어(backing store)라고도 불린다. 디스크 내에 파일 시스템과 별도로 존재하며 저장공간이 상대적으로 짧은 저장공간이라고 할 수 있다. 충분히 큰 저장공간이어야 하며, 접근 속도가 보장되어야 한다.
- 스왑 인(swap in) : 디스크 -> 메모리
- 스왑 아웃(swap out) : 메모리 -> 디스크
중기 스케줄러에 의해 스왑 아웃 대상 프로세스가 선정된다. 선정된 프로세스의 주소 공간의 내용을 통째로 스왑 영역에 스왑 아웃시킨다. 메모리에 존재하는 프로세스의 수를 조절하는 것이 가장 중요한 기능이다. 주소 공간이 순차적으로 저장되기 때문에, 스와핑에는 탐색 시간, 회전 지연시간보다는 전송시간이 대부분을 차지한다.
물리적 메모리 할당
연속 할당(contiguous allocation)
각각의 프로세스를 물리적 메모리의 연속적인 공간에 올리는 방식
◆ 고정 분할 방식(fixed partition allocation)
메모리를 주어진 개수만큼의 영구적인 분할(partition)로 미리 나누어두고 각 분할에 하나의 프로세스를 적재한다
분할의 크기를 동일하게 할 수도, 다르게 할 수도 있다
하나의 분할에는 하나의 프로세스만 적재할 수 있기 때문에 적재 가능한 프로그램의 수와 프로그램의 최대 크기가 제한된다
외부 조각(external fragmentation)과 내부 조각(internal fragmentation)이 발생할 수 있다
▶외부 조각 ? 프로그램의 크기보다 분할의 크기가 작을 때, 비어있음에도 프로그램을 적재하지 못하는 공간
▶내부 조각 ? 프로그램의 크기보다 분할의 크기가 클 때, 적재하고 남는 메모리 공간
◆ 가변 분할 방식(variable partition allocation)
메모리에 적재되는 프로그램의 크기에 따라 분할의 크기, 개수가 동적으로 변하는 방식
분할을 관리할 수 있는 기법이 필요
내부 조각은 발생하지 않으며, 외부 조각이 발생할 가능성이 있다
주요 쟁점 : '가용 공간 중 어떤 위치에 올릴 것인지 결정하는 것'
=> 동적 메모리 할당 문제(dynamic storage-allocation problem)
- 최초 적합(First-fit): 가용 공간 중 가장 먼저 찾아지는 곳에 프로세스를 할당한다
- 최적 적합(Best-fit): 가용 공간 중 크기가 가장 작은 공간을 찾아 프로세스를 할당한다
- 최악 적합(Worst-fit) : 가용 공간 중 크기가 가장 큰 공간을 찾아 프로세스를 할당한다
▶컴팩션(compaction) ? 가변 분할 방식에서 발생하는 외부 조각 문제를 해결하기 위해, 사용 중인 메모리 영역을 한쪽으로 몰고 가용 공간들을 다른 한쪽으로 모아서 하나의 큰 가용 공간을 만드는 작업. 비용이 매우 많이 드는 작업
불연속 할당(noncontiguous allocation)
하나의 프로세스를 물리적 메모리의 여러 영역에 분산해 적재하는 방식
◆ 페이징(paging) 기법 : 페이지 단위 적재
프로세스의 주소 공간을 동일한 크기의 페이지 단위로 나누어 물리적 메모리의 서로 다른 위치에 페이지들을 저장하는 방식
물리적 메모리를 페이지와 동일한 크기의 프레임으로 미리 나누어둔다. 메모리에 올리는 단위가 페이지 이므로, 프레임이 비어있다면 어떤 위치든 사용이 가능하다(= 동적 메모리 할당 문제가 생기지 않는다)
특정 프로세스의 몇 번째 페이지가 물리적 메모리의 몇 번째 프레임에 들어있는지 페이지별 주소 변환 정보를 유지하기 위해 페이지 테이블(page table)을 가지고 있다.
외부 조각 문제는 발생하지 않으나, 마지막 페이지에서 내부 조각이 발생할 수 있다
▶ 주소 변환 기법
페이징 기법에서는 논리적 주소를 페이지 번호(p)와 페이지 오프셋(d)으로 나누어 주소 변환에 사용한다
페이지 번호 : 페이지 테이블 접근 인덱스. 해당 인덱스의 항목이 페이지의 물리적 메모리 상의 기준 주소가 된다
페이지 오프셋 : 기준 주소 값에 오프셋 값을 더하면 대응하는 물리적 주소를 얻을 수 있다
▶ 페이지 테이블
페이징 기법에서 주소 변환을 하기 위한 자료구조로, 물리적 메모리에 위치한다. 운영체제는 아래 2개의 레지스터를 사용하여 페이지 테이블에 접근한다.
페이지 테이블 기준 레지스터(page-table base register) : 페이지 테이블의 시작 위치
페이지 테이블 길이 레지스터(page-table length register) : 페이지 테이블의 크기
TLB(Translation Look-aside Buffer) : 페이지 테이블 접근 오버헤드를 줄이고 메모리의 접근 속도를 향상하기 위한 고속의 주소 변환용 하드웨어 캐시, 모든 페이지에 대한 주소 변환 정보를 가지고 있지 않기 때문에 페이지 번호와 이에 대응하는 프레임 번호가 쌍으로 저장된다. TLB의 모든 항목을 다 찾아봐야 하는 오버헤드를 줄이기 위해 일반적으로 병렬 탐색(Parallel search)이 가능한 연관 레지스터(associative register)를 사용한다.
※ 병렬 탐색 ? 모든 항목을 동시에 탐색하는 것
▶계층적 페이징
주소 공간이 매우 큰 프로그램을 사용할 경우, 페이지 테이블에 너무 많은 주소 공간을 할애하게 된다. 이를 해결하기 위해 2단계 페이징(two-level paging) 기법을 사용한다
외부 페이지 테이블(outer page table)과 내부 페이지 테이블(inner page table)을 사용하여 사용되지 않는 주소 공간에 대해서 외부 페이지 테이블의 항목을 NULL로, 내부 페이지 테이블은 생성하지 않는다. 이를 통해 공간적인 낭비는 줄일 수 있지만, 시간적인 손해가 뒤따른다. 이때 TLB를 활용하여 시간적인 손해도 줄일 수 있다.
▶역 페이지 테이블
물리적 메모리의 페이지 프레임 하나당 페이지 테이블에 하나씩의 항목을 두는 방식
논리적 주소가 아닌, 물리적 주소에 대해 페이지 테이블을 만든다. 시스템 전체에 하나의 페이지 테이블만 가지고 있으며, 테이블의 각 항목은 프로세스 번호(pid)와 그 프로세스 내의 논리적 페이지 번호를 담는다. 연관 레지스터를 사용하여 병렬 탐색을 가능하게 하고 시간적 효율성을 높일 수 있다.
▶공유 페이지
공유 코드를 담고 있는 페이지. 물리적 메모리에 하나만 적재되어 있으며, 각 프로세스의 논리적 주소 공간에서 동일한 위치에 존재해야 하는 제약점이 있다.
※ 공유 코드(shared code) : 메모리 공간의 효율적인 사용을 위해 여러 프로세스에 의해 공통으로 사용될 수 있도록 작성된 코드. 재진입 가능 코드(re-entrant code) / 순수 코드(pure code)라고도 불린다. 읽기 전용의 특성을 가지고 있다.
↔사유 페이지(private page) : 프로세스 별로 독자적으로 사용하는 페이지
▶메모리 보호
페이지 테이블은 메모리 보호를 위해 보호 비트(protection bit)와 유효-무효 비트(valid-invalid bit)를 두고 있다.
- 보호 비트 : 어떤 접근을 허용하는지 ex) 읽기 전용, 읽기-쓰기 전용
- 유효-무효 비트 : 메모리에 페이지가 존재하는지 아닌지
◆ 세그먼테이션(segmentation) 기법 : 코드, 데이터, 스택 등 의미 있는 단위인 세그먼트 단위 적재
의미를 가질 수 있는 논리적인 단위(logical unit)로 나눈 것이기 때문에 크기가 균일하지 않으나, 공유와 보안 측면에서 효과적이다. 보호 비트와 유효 비트를 사용한다. 외부 조각이 발생하게 되며, 어떤 가용 공간에 할당할 것인지 결정하기 위해 최초 적합, 최적 적합 방식을 사용한다.
세그먼테이션 기법에서는 아래의 두 레지스터를 활용하여 주소를 변환한다.
- 세그먼트 테이블 기준 레지스터(STBR : Segment-Table Base Register) : 실행 중인 프로세스의 세그먼트 테이블 시작 주소
- 세그먼트 테이블 길이 레지스터(STLR : Segment-Table Length Register) : 세그먼트의 개수
주소 변환 전에 아래 두 가지 사항을 확인하여 예외 상황을 발생시킨다.
첫째. 세그먼트 번호가 STLR에 저장된 값보다 작은 값인지
둘째. 논리적 주소의 오프셋 값이 그 세그먼트의 길이보다 작은 값인지
◆ 페이지드 세그먼테이션(paged segmentation) 기법 : 세그먼트 하나를 다수의 페이지로 구성
페이징 기법과 세그먼테이션 기법의 장점만 취하는 방법으로, 프로그램을 의미 단위의 세그먼트로 나눈 후 세그먼트를 페이지의 집합으로 구성하는 방식. 세그먼트의 크기는 페이지 크기의 배수가 된다.
참고 자료
'IT Basic > Operating System' 카테고리의 다른 글
[OS] 8장 가상메모리 (0) | 2022.01.05 |
---|---|
데드락(Deadlock, 교착상태)에 대해 (0) | 2021.12.30 |
[OS] 6장 CPU 스케줄링 (0) | 2021.12.28 |
[OS] 5장 프로세스 관리 (0) | 2021.12.22 |
[OS] 4장 프로그램의 구조와 실행 (0) | 2021.12.22 |
댓글