메모리 관리
- 메모리는 주소를 통해 접근하는 저장 장치이다.
- byte 단위로 메모리 주소가 부여된다.
- 효율적인 운영을 위해 연속된 일련의 영역을 행정구역처럼 4kb 단위로 묶어서 페이지라고 부르며 사용
- 페이지 내에서 바이트별 위치 구분을 위해서는 12비트가 필요하다.
- 메모리를 어떠한 행정구역으로 나누어 관리할 것인가?
- 프로그램이 물리적 메모리에 어떻게 올라가서 주소를 할당받게 되는가?
주소 바인딩
- 주소바인딩이란 프로세스의 논리적 주소를 물리적 메모리 주소로 연결시켜 주는 작업이다.
- 프로그램이 실행을 위해 메모리에 적재되면 그 프로세스를 위한 독자적인 주소 공간이 생성된다.
- CPU는 프로세스마다 독립적으로 갖는 논리적 주소에 근거해 명령을 실행한다.
- 물리적 주소는 물리적 메모리에 실제로 올라가는 위치를 말한다. 보통 물리적 메모리의 낮은 주소영역에는 운영체제가 올라가고, 높은 주소 영역에는 사용자 프로세스들이 올라간다.
- 주소 바인딩 방식은 프로그램이 적재되는 물리적 메모리의 주소가 결정되는 시기에 따라 분류할 수 있다.
- 컴파일 타임 바인딩
- 물리적 메모리 주소가 프로그램을 컴파일 할 때 결정되는 주소 바인딩 방식
- 컴파일하는 시점에 해당 프로그램이 물리적 메모리의 몇 번지에 위치할 것인지 결정된다.
- 절대 코드(absolute code)를 생성하는 바인딩 방식이라고도 말한다.
- 프로그램이 올라가 있는 물리적 메모리의 위치를 변경하기 위해서는 다시 컴파일해야 하기 때문에 잘 사용하지 않는 방법이다.
- 로드 타임 바인딩
- 프로그램이 실행이 시작될 때 물리적 메모리 주소가 결정되는 주소 바인딩 방식
- 로더(loader)의 책임하에 물리적 메모리 주소가 부여되며 프로그램이 종료될 때까지 물리적 메모리상의 위치가 고정된다.
- 로더란 사용자 프로그램을 메모리에 적재시키는 프로그램을 말한다.
- 컴파일러가 재배치 가능 코드(relocatable code)를 생성한 경우에 가능한 주소 바인딩 방식이다.
- 실행시간 바인딩(execution time binding, run time binding)
- 프로그램이 실행 중인 경우에도 그 프로그램이 위치한 물리적 메모리상의 주소가 변경될 수 있는 바인딩 방식
- CPU가 주소를 참조할 때마다 해당 데이터가 물리적 메모리의 어느 위치에 존재하는지, 주소 매핑 테이블(address mapping table)을 이용해 바인딩을 점검해야 한다.
- 기준(base) 레지스터와 한계(limit) 레지스터를 포함하여 MMU(memory management unit)의 하드웨어적인 지원이 필요하다.
- MMU는 CPU가 특정 프로세스의 논리적 주소를 참조하려고 할 때 그 주소 값에 기준 레지스터의 값을 더해 물리적 주소값을 얻어낸다. 기준 레지스터에는 특정 프로세스의 물리적 메모리 시작 주소가 저장되어 있다.
- MMU 기법에서는 프로그램의 주소 공간이 물리적 메모리의 한 장소에 연속적으로 적재되는 것으로 가정하기 때문에 그 프로그램이 적재되는 물리적 메모리상의 시작 주소만 알면 주소 변환이 쉽게 가능하다.
- MMU 기법에서 사용자 프로그램과 CPU는 논리적 주소만을 다룰 뿐 실제 물리적 주소는 알지 못하며 알아야 할 필요도 없다.
- MMU 기법에서는 문맥교환으로 CPU에서 수행 중인 프로세스가 바뀔 때마다 재배치 레지스터의 값을 그 프로세스에 해당되는 값으로 재설정함으로써 각 프로세스에 맞는 주소에 접근할 수 있다.
- 메모리 참조 시 한계 레지스터로 프로세스가 자신의 주소 공간을 넘어서는 메모리 참조를 우선 체크하여 메모리 보안을 유지할 수 있다. 한계레지스터를 넘어서는 다른 프로세스에 접근하려는 시도이므로 트랩을 발생시켜 해당 프로세스를 강제로 종료시킨다.
- 컴파일 타임 바인딩
메모리 관리
- 동적 로딩(dynamic loading)
- 여러 프로그램이 동시에 메모리에 올라가서 수행되는 다중 프로그래밍 환경에서 메모리 사용의 효율성을 높이기 위해 사용하는 기법이다.
- 프로세스의 주소 공간 전체를 메모리에 다 올려놓지 않고 프로세스 내에서 실행에 필요한 부분이 실제로 불릴 때마다 그 부분만을 메모리에 적재하는 방식을 사용한다.
- 동적로딩은 운영체제의 특별한 지원 없이 프로그램 자체에서 구현이 가능하며 운영체제가 라이브러리를 통해 지원할 수도 있다.
- 동적 연결(dynamic linking)
- linking이란 프로그래머가 작성한 소스 코드를 컴파일하여 생성된 목적(object) 파일과 이미 컴파일된 라이브러리 파일들을 묶어 하나의 실행파일을 생성하는 과정을 말한다.
- 동적 연결은 컴파일을 통해 생성된 목적 파일과 라이브러리 파일 사이의 연결을 프로그램의 실행 시점까지 지연시키는 기법이다.
- 반대로 정적(static) 연결에서는 프로그래머가 작성한 코드와 라이브러리 코드가 모두 합쳐져서 실행파일이 생성된다. 상대적으로 실행파일의 크기가 크며 동일한 라이브러리를 각 프로세스가 개별적으로 메모리에 적재해야 하므로 물리적 메모리가 낭비되는 단점이 있다.
- 동적 연결에서는 라이브러리가 실행 시점에 연결된다. 즉 실행 파일에 라이브러리 코드가 포함되지 않으며, 프로그램이 실행되면서 라이브러리 함수를 호출할 때가 되어서야 라이브러리에 대한 연결이 이루어진다.
- 동적연결을 가능하게 하기 위해 실행파일의 라이브러리 호출 부분에 해당 라이브러리 위치를 찾기 위한 스텁(stub)이라는 작은 코드를 둔다. 스텁을 통해 해당 라이브러리가 이미 메모리에 존재하면 직접 참조하며, 존재하지 않으면 디스크에서 동적 라이브러리 파일을 찾아 메모리로 적재한 후 수행한다.
- 동적연결에서는 공통으로 사용하는 라이브러리를 한 번만 메모리에 적재하므로 메모리를 효율적으로 사용할 수 있다.
- 동적 연결 기법은 운영체제의 지원을 필요로 한다.
- 중첩(overlays)
- 프로세스의 주소 공간을 분할해 실제 필요한 부분만을 메모리에 적재하는 기법
- 초창기의 컴퓨터 시스템에서 물리적 메모리의 크기 제약으로 인해 하나의 프로세스조차도 메모리에 한꺼번에 올릴 수 없을 때 프로세스의 주소 공간을 분할해서 당장 필요한 일부분을 메모리에 올려 실행하고 해당 부분에 대한 실행이 끝난 후에 나머지 부분을 올려 실행하는 기법을 뜻한다.
- 동적로딩에서는 메모리의 이용률을 향상시키기 위해 프로세스의 주소 공간 중 당장 실행에 필요한 부분을 그때그때 메모리에 동적으로 올려서 더 많은 프로세스를 동시에 올려놓고 실행하기 위한 용도였다면, 중첩은 단일 프로세스만을 메모리에 올려놓는 환경에서 메모리 용량보다 큰 프로세스를 실행하기 위한 어쩔 수 없는 선택이었다.
- 스와핑(swapping)
- 메모리에 올라온 프로세스의 주소 공간 전체를 디스크의 스왑영역(swap area)에 일시적으로 내려놓는 것을 의미한다. 내리는 작업은 swap out, 메모리로 다시 올리는 작업을 swap in이라고 부른다.
- 스왑 영역은 백킹스토어(backing store)라고도 부르며 디스크 내에 파일 시스템과는 별도로 존재하는 일정 영역을 말한다.
- 중기 스케줄러에 의해 스왑 아웃 대상으로 선정된 프로세스에 대해서 메모리 주소 공간 내용을 통째로 스왑 아웃시킨다.
- 스와핑은 메모리에 존재하는 프로세스의 수를 조절하는 역할을 한다. 스와핑을 통해 프로세스당 메모리의 양이 지나치게 적어지는 것을 방지한다.
- 스와핑에서는 보통 디스크 내의 스왑 영역에 프로세스의 주소 공간이 순차적으로 저장되기 때문에, 디스크의 탐색 시간이나 회전지연시간보다는 디스크 섹터에서 실제 데이터를 읽고 쓰는 전송 시간이 소요시간의 대부분을 차지한다.
물리적 메모리의 할당방식
- 물리적 메모리는 운영체제 상주 영역과 사용자 프로세스 영역으로 나뉘어 사용된다.
- 운영체제 상주 영역은 인터럽트 벡터와 함께 물리적 메모리의 낮은 주소 영역을 사용하며, 운영체제 커널이 이곳에 위치한다.
- 사용자 프로세스 영역은 물리적 메모리의 높은 주소영역을 사용하며 여러 사용자 프로세스들이 이곳에 적재되어 실행된다.
- 사용자 프로세스 영역의 관리 방법은 프로세스를 메모리에 올리는 방식에 따라 분류할 수 있다.
- 연속할당(contiguous allocation)
- 각각의 프로세스를 물리적 메모리의 연속적인 공간에 올리는 방식이다.
- 물리적 메모리를 다수의 분할로 나누어 하나의 분할에 하나의 프로세스가 적재되도록 한다.
- 고정분할
- 물리적 메모리를 고정된 크기의 분할(partition)로 미리 나누어두는 방식
- 동시에 메모리에 올릴 수 있는 프로그램의 수가 고정돼있으며 수행 가능한 프로그램의 최대 크기도 제한된다.
- 외부조각과 내부조각이 발생할 수 있다.(external, internal fragmentation)
- 가변분할
- 분할을 미리 나누어놓지 않은 채 프로그램이 실행되고 종료되는 순서에 따라 분할을 관리하는 방식이다.
- 메모리에 적재되는 프로그램의 크기에 따라 분할의 크기, 개수가 동적으로 변한다.
- 동적 메모리 할당 문제
- 물리적 메모리 내 가용 공간 중 어떤 위치에 프로세스를 올릴 것인가? 실험 결과 최초적합 방식이나 최적적합방식이 보다 효과적이다.
- 최초적합 방법
- 가용 공간을 차례대로 살펴보면서 프로그램보다 작지 않은 가용공간이 최초로 발견되면 할당
- 최적적합 방법
- 프로그램의 크기 이상인 가장 작은 가용 공간을 찾아 할당
- 모든 가용 공간 리스트를 탐색하는 오버헤드 발생
- 다수의 매우 작은 가용공간들이 생성될 수 있는 단점 존재
- 최악적합 방법
- 가용 공간 중에서 가장 크기가 큰 곳에 할당
- 모든 가용 공간 리스트를 탐색하는 오버헤드 발생
- 상대적으로 더 큰 프로그램을 담을 수 있는 가용공간을 빨리 소진할 수 있는 단점 존재
- 컴팩션(compation)
- 가변분할 방식에서 발생하는 외부조각 문제를 해결하기 위한 방법
- 물리적 메모리 중에서 프로세스에 의해 사용 중인 메모리 영역과 가용공간을 각각 한쪽으로 모아서 하나의 큰 가용 공간을 만드는 방법
- 수행 중인 프로세스의 물리적 메모리 위치를 옮겨야 하므로 프로그램의 실행 도중에 프로세스의 주소가 동적으로 바뀔 수 있는 실행시간 바인딩 방식이 지원되는 환경에서만 수행가능
- 불연속할당(noncontiguous allocation)
- 하나의 프로세스를 물리적 메모리의 여러 영역에 분산해 적재하는 방식
- 페이징(paging) 기법
- 각 프로세스의 주소 공간을 동일한 크기의 페이지로 잘라서 메모리에 페이지 단위로 적재함.
- 물리적 메모리를 페이지와 동일한 크기의 프레임으로 미리 나누어둔다.
- 논리적 주소를 물리적 주소로 변환할 때 페이지 단위로 이루어져야 하므로 특정 프로세스의 몇 번째 페이지가 물리적 메모리의 몇번째 프레임에 들어있다는 페이지별 주소 변환을 위한 페이지 테이블을 모든 프로세스가 가지고 있어야 한다.
- 주소 변환 기법
- 논리적 주소를 페이지 번호와 페이지 오프셋으로 나누어 사용
- 페이지 번호는 페이지 테이블 접근 시 인덱스로 사용되고 해당 페이지의 물리적 메모리상의 시작 위치가 저장되어 있다.
- 페이지 오프셋은 하나의 페이지 내에서의 변위를 알려준다.
- 페이지 테이블
- 페이지 테이블은 물리적 메모리에 위치하며 CPU에서 실행 중인 프로세스의 페이지 테이블에 접근하기 위해 운영체제는 페이지 테이블 기준 레지스터와 페이지 테이블 길이 레지스터를 사용한다.
- 페이지 테이블 접근 오버헤드를 줄이기 위해서 TLB라고 불리는 고속의 주소 변환용 하드웨어 캐시가 사용되기도 한다.
- 계층적 페이징
- 페이지 테이블을 위한 메모리 공간의 사용은 낭비가 심하다.
- 주소변환을 위해 외부 페이지 테이블과 내부 페이지 테이블의 두 단계에 걸친 페이지 테이블을 사용
- TLB를 함께 사용 시 메모리 접근 시간에 대한 오버헤드를 줄일 수 있다.
- 역페이지 테이블
- 물리적 메모리의 페이지 프레임 하나당 페이지 테이블에 하나씩의 항목을 두는 방식
- 물리적 주소에 대해 페이지 테이블을 시스템 전체에 대해 1개만 만든다.
- 페이지 테이블은 프로세스번호(pid)와 그 프로세스 내의 논리적 페이지 번호를 담고 있다.
- 공유 페이지
- 공유페이지는 공유 코드를 담고 있는 페이지를 의미한다.
- 공유 코드는 메모리 공간의 효율적인 사용을 위해 여러 프로세스에 의해 공통으로 사용될 수 있도록 작성된 코드로 재진입 가능코드 또는 순수코드라고도 불리며 읽기 전용의 특성을 가지고 있다.
- 공유페이지는 그 페이지를 공유하는 모든 프로세스의 주소 공간에서 동일한 페이지 번호를 가져야 한다.
- 공유페이지는 공유 코드를 담고 있는 페이지를 의미한다.
- 메모리 보호
- 페이지 테이블의 각 항목에는 메모리 보호를 위한 보호 비트와 유효-무효 비트를 두고 있다.
- 보호 비트에는 각 페이지에 대해 읽기-쓰기/읽기 전용 등의 접근 권한을 설정하는 데 사용
- 유효비트가 유효로 세팅되어 있으면 해당 메모리 프레임에 페이지가 존재하므로 접근 허용된다.
- 유효비트가 무효로 세팅되어있으면 프로세스가 그 주소 부분을 사용하지 않거나, 해당 페이지가 물리적 메모리에 올라와 있지 않고 백킹스토어에 존재하므로 해당 메모리 프레임에 유효한 접근 권한이 없다는 의미를 가진다.
- 세그먼테이션(segmentation) 기법
- 프로그램의 주소 공간을 코드, 데이터, 스택 등 의미 있는 단위인 세그먼트로 나누어 적재함.
- 크기가 균일하지 않은 세그먼트들을 메모리에 적재하는 부가적인 관리 오버헤드가 생긴다.
- 세그먼트 단위로 프로세스 간의 공유나 프로세스 내의 접근 권한 보호가 이루어질 수 있다.
- 페이지드 세그먼테이션(paged segmentation) 기법
- 세그먼트 하나를 다수의 페이지로 구성하는 기법으로 두 방법의 장점만을 취하는 방법
- 의미단위의 세그먼트가 동일한 크기 페이지들의 집합으로 구성된다.
- 외부의 세그먼트 테이블과 내부의 페이지 테이블을 사용하여 주소변환을 수행한다.
- 연속할당(contiguous allocation)
댓글