운영체제와 정보기술의 원리

7 minute read

[7장] 메모리 관리

컴퓨터에서는 byte 단위로 메모리 주소를 부여하므로 32비트 주소 체계에서는 2^32바이트만큼의 메모리 주소가 할당될 수 있다.

보통 4KB(2^12) 단위로 묶어 페이지로 나눠 관리한다.

1. 주소 바인딩

프로그램이 실행을 위해 메모리에 적재되면 그 프로세스를 위한 독재적인 주소 공간이 생성된다. 이를 논리적 주소 혹은 가상 주소 라고 한다.

  • 논리적 주소

    각 프로세스마다 독립적으로 할당되어 0번지부터 시작

  • 물리적 주소

    물리적 메모리에 실제로 올라가는 위치

    낮은 주소 영역에는 OS가, 높은 주소 영역에는 사용자 프로세스가 올라간다.

프로세스는 프로그램이 물리적 메모리에 올라가 있어야 한다. 그러고 CPU가 기계어 명령을 수행하기 위해 논리적 주소를 통해 메모리 참조를 해 논리적 주소를 물리적 메모리 주소로 연결할 수 있다. 이를 주소 바인딩 이라고 한다.

주소 바인딩 방식

  • 컴파일 타임 바인딩

    컴파일을 하는 시점에 해당 프로그램이 물리적 메모리의 몇 번지에 위치할 것인지 결정하는 것

    프로그램이 절대주소로 적재되므로 절대코드를 생성하는 바인딩 방식

    메모리 위치 바꾸려면 컴파일 다시 해야해서 시분할에선 잘 안씀

  • 로드 타임 바인딩

    로더의 책임 하에 물리적 메모리 주소가 부여되고 종료될 때까지 고정된다.

    로더는 사용자 프로그램을 메모리에 적재시키는 프로그램

    컴파일러가 재배치 가능 코드를 생성한 경우에 가능한 방식

  • 실행 시간 바인딩

    프로그램 실행 후에도 그 프로그램이 위치한 물리적 메모리 주소가 변경될 수 있는 방식

    주소 매핑 테이블을 이용해 해당 데이터가 물리적 메모리의 어느 위치에 존재하는지 점검

    실행시간 바인딩 방식이 가능하기 위해 기준 레지스터, 한계 레지스터, MMU라는 하드웨어 지원 필요

    • MMU

    논리적 주소를 물리적 주소로 매핑해주는 하드웨어 장치

    CPU가 특정 프로세스의 논리적 주소를 참조하려고 할 때 그 주소값에 기준 레지스터의 값을 더해 물리적 주소값을 얻어낸다.

    물리적 메모리 상의 시작 주소만 알면 손쉽게 주소 변환할 수 있다.

    이 때 논리적 주소는 기준 레지스터로부터 얼마나 떨어져 있는지 나타내는 일종의 오프셋

    • 기준 레지스터

      재배치 레지스터로 프로세스의 물리적 메모리 시작 주소를 가지고 있다.

    • MMU의 결과가 프로세스의 주소 공간을 벗어난다면?

      메모리 보안이 이뤄지지 않아 다른 프로그램 영역을 침범할 수 있다.

      이를 방지하기 위해 한계 레지스터 를 이용해 프로세스가 자신의 주소 공간을 넘어서는 메모리를 참조하려고 하는지 체크한다.

      한계 레지스터에는 CPU에서 수행 중인 프로세스의 논리적 주소의 최댓값, 그 프로세스의 크기를 담는다.

      만약 시도하는 영역이 올바르지 않으면 트랩을 발생시켜 해당 프로세스를 강제종료한다.

스크린샷 2021-08-10 오전 12 35 35


2. 메모리 관리와 관련된 용어

1) 동적로딩

여러 프로그램이 동시에 메모리에 올라가서 수행되는 다중 프로그래밍 환경에서 메모리 사용의 효율성 높이기 위해 사용하는 방식으로 프로세스가 시작될 때 전체를 메모리에 올리지 않고 호출되는 부분만 메모리에 적재하는 방식

에러 처리 같이 항상 떠있을 필요가 없는 애들에 대한 메모리 효율을 높이는 것이다.

프로그램 자체에서 구현할 수도, 운영체제가 지원할 수도 있다.

java는 대표적인 동적 로딩 프로그램으로 static을 사용하지 않는 한 동적으로 클래스가 로딩된다.

2) 동적연결

프로그래머가 작성한 소스 코드를 컴파일하여 생성된 목적 파일과 이미 컴파일된 라이브러리 파일들을 묶어 하나의 실행파일을 생성하는 과정을 프로그램의 실행 시점까지 지연시키는 기법

라이브러리의 위치를 찾기 위해 스텁이라는 작은 코드를 두어 해당 라이브러리가 메모리에 존재하는지 확인하고 있으면 참조, 없으면 동적 라이브러리 파일을 찾아 메모리로 적재

여러 프로그램이 공유할 수 있다는 장점, 더 많은 프로세스를 동시에 올려놓고 실행하기 위함

3) 중첩

프로세스의 주소 공간을 분할해 실제 필요한 부분만 메모리에 적재하는 기법

메모리 용량보다 큰 단일 메모리를 메모리에 올려놓기 위함, 잘 안씀

4) 스와핑

메모리에 올라온 프로세스의 주소 공간 전체를 디스크의 스왑 영역(백킹스토어)에 일시적으로 내려놓는 것

스왑 영역은 프로세스 수행 중에만 일시적으로 저장하는 공간으로 사용자의 프로세스를 담을만큼 크고 속도도 보장되어야 한다.

디스크에서 메모리로 올리는 걸 스왑 인, 메모리에서 디스크로 내리는 것을 스왑 아웃

메모리에 존재하는 프로세스의 수를 조절함으로써 너무 많은 프로그램이 올라와 메모리를 조금씩 가져가 성능이 떨어지는 것을 방지한다.

  1. 중기 스케줄러에 의해 스왑 대상 프로세스 선정
  2. 주소 공간의 내용을 통째로 디스크 스왑 아웃

디스크 내의 스왑 영역에 프로세스의 주소 공간이 순차적으로 저장되므로 탐색시간이나 회전지연시간보다는 전송시간이 오래걸린다.


3. 물리적 메모리의 할당 방식

  • 운영체제 상주 영역

    인터럽트 벡터와 함께 물리적 메모리의 낮은 주소 영역으로 운영체제 커널

  • 사용자 프로세스 영역

    물리적 메모리의 높은 주소 영역으로 여러 사용자 프로세스

사용자 프로세스 영역

  • 연속할당

    물리적 메모리를 다수의 분할로 나누어 하나의 분할에 하나의 프로세스가 적재되도록 하여 각 프로세스를 물리적 메모리의 연속적 공간에 올림

    • 고정분할

      물리적 메모리를 고정된 크기의 분할로 미리 나누어두는 방식

      분할의 크기는 모두 동일할 수도, 서로 다를수도 있다.

      동시에 올릴 수 있는 프로그램의 수가 고정되어 있고 수행 가능한 프로그램의 최대 크기도 제한된다.

      외부조각: 프로그램의 크기보다 분할의 크기가 작은 경우, 작은거 오면 사용 가능

      내부조각: 프로그램의 크기보다 분할의 크기가 큰 경우, 사용불가

    • 가변분할

      미리 나누어두지 않은 채 프로그램이 실행되고 종료되는 순서에 따라 분할을 관리하는 방식

      프로그램의 크기를 고려해 메모리를 할당하고 기술적으로 관리할 수 있는 기법 필요

      프로그램 종료 시 외부조각 발생 가능, 내부조각 발생 x

      • 동적 메모리 할당 문제

        주소 공간의 크기가 n인 프로세스를 메모리에 올릴 때 물리적 메모리 내 가용 공간 중 어떤 위치에 올릴 것인지 사용 중인 메모리 공간과 사용하지 않는 가용 공간에 대한 정보를 각각 관리

        • 최초적합

          크기가 n 이상인 가용 공간 중 가장 먼저 찾아지는 곳에 할당

        • 최적적합

          크기가 n 이상인 가장 작은 가용 공간에 할당

          시간적 오버헤드, 공간적 효율성

        • 최악적합

          크기가 가장 큰 곳에 할당

      • 컴팩션

        물리적 메모리 중에서 프로세스에 의해 사용 중인 메모리 영역을 한쪽으로 몰아 하나의 큰 가용 공간 만드는 것

        비용이 매우 많이 듦. 실행시간 바인딩 시에만 적용 가능

  • 불연속할당

    하나의 프로세스를 물리적 메모리의 여러 영역에 분산해 적재하는 방식

    • 페이징

      각 프로세스의 주소 공간을 동일한 크기의 페이지로 잘라 메모리에 페이지 단위로 적재

    • 세그먼테이션

      프로그램 주소 공감을 코드, 데이터, 스택 등의 의미 있는 단위인 세그먼트로 나누어 세그먼트 단위로 적재


4. 페이징 기법

프로세스의 주소 공간을 동일한 크기의 페이지 단위로 나누어 물리적 메모리의 서로 다른 위치에 페이지 저장하는 방식

물리적 메모리를 페이지와 동일한 크기의 프레임으로 나누어 빈 프레임이 있으면 사용할 수 있도록 한다.

하나의 프로세스에서도 위치가 달라 몇번째 페이지가 물리적 메모리의 몇번째 프레임에 있는지 각 프로세스가 페이지 테이블 에 저장한다. 가질 수 있는 페이지 개수만큼 주소 변환 엔트리를 가진다.

외부 조각은 없지만 프로세스 마지막엔 내부조각 있을 수도 있다.

1) 주소 변환 기법

CPU가 사용하는 논리적 주소를 페이지 번호(P)페이지 오프셋(d) 으로 나누어 주소 변환에 사용

  • 페이지 번호: 각 페이지별 주소 변환 정보를 담고 있는 페이지 테이블 접근 시 인덱스

  • 해당 인덱스의 항목(엔트리): 그 페이지의 물리적 메모리상의 기준 주소, 시작 위치

  • 페이지 오프셋: 페이지 내에서의 변위로 기준 주소값에 더해 논리적 주소에 대응하는 물리적 주소 얻을 수 있음

2) 페이지 테이블의 구현

  • 페이지 테이블 기준 레지스터: 메모리 내에서의 페이지 테이블 시작 위치
  • 페이지 테이블 길이 레지스터: 페이지 테이블의 크기

메모리에 한 번 접근하기 위해서는 주소 변환을 위한 페이지 테이블 접근, 변환된 주소에서 실제 데이터에 접근이 이뤄져야 한다.

  • Translation Look-aside Buffer

    고속의 주소 변환용 하드웨어 캐시로 페이지 테이블 접근 오버헤드를 줄이고 메모리 접근 속도 향상

    비싸서 자주 참조되는 페이지에 대한 정보만 가진다. 문맥교환되면 TLB 내용 다 없애야 한다.

    페이지 테이블은 페이지 번호<->프레임 번호 용이하지만, TLB는 모든 페이지 없으므로 페이지 번호, 프레임 번호가 같이 저장되어야 한다.

    TLB의 모든 항목을 다 찾아보는 오버헤드 줄이기 위해 모든 항목 동시 탐색 가능한 병렬 탐색이 가능한 연관 레지스터 사용

스크린샷 2021-08-10 오전 1 34 31

  • 연관 레지스터를 사용한 메모리 접근 시간 : 2 + e - a

3) 계층적 페이징

프로세스 증가에 따른 주소 변환을 위한 페이지 테이블에 메모리 먹히지 않도록 하는 것

사용되지 않는 주소 공간에 대해서는 외부 페이지 테이블 을 null로, 내부 페이지 테이블을 생성하지 않음

공간은 얻지만 시간은 잃는다.

외부 페이지 테이블로부터 P1만큼 떨어진 위치에서 내부 페이지 테이블의 주소를 얻고 내부 페이지 테이블로부터 P2만큼 떨어진 위치에서 요청된 페이지가 존재하는 프레임 위치 얻고, 프레임으로부터 d만큼 떨어진 곳에서 원하는 정보 얻는다.

내부 페이지 테이블 자체를 하나의 프레임에 보관하게 된다.

스크린샷 2021-08-10 오전 1 46 28 )

다단계 페이지 테이블을 사용하면 페이지 테이블에 사용되는 메모리 공간 소모는 줄일 수 있지만 메모리 접근 횟수가 늘어나 메모리 접근 시간이 크게 늘어나는 문제 -> TLB 해결

4) 역페이지 테이블

물리적 메모리의 페이지 프레임 하나당 페이지 테이블에 하나씩의 항목을 두는 방식

논리적 주소에 대해 페이지 테이블을 만드는 것이 아니라 물리적 주소에 대해 시스템 전체에 대해 하나의 페이지 테이블 생성

탐색에 굉장히 오랜 시간이 걸리므로 메모리 유지 대신 연관 레지스터에 보관해 병렬탐색 사용

스크린샷 2021-08-10 오전 1 54 42

5) 공유 페이지

공유 코드는 메모리 공간의 효율적인 사용을 위해 여러 프로세스에 공통으로 사용될 수 있도록 작성된 재진입 가능, 순수, 읽기전용의 특성을 가진 코드

공유 페이지는 그런 공유 코드를 담고 있는 페이지로 모든 프로세스의 논리적 공간에서 동일한 페이지 번호를 가져야 한다.

사유 페이지 는 프로세스들이 공유하지 않고 독자적으로 사용하는 페이지로 논리적 공간 중 어디에 있어도 무방

6) 메모리 보호

  • 보호비트

    각 페이지에 대한 접근 권한의 내용, 어떠한 접근을 허용하는지

  • 유효-무효 비트

    해당 페이지의 내용이 유효한지 있으면 유효, 없거나 권한 없으면 무효


5. 세그멘테이션

프로세스의 주소 공간을 의미 단위인 세그먼트로 나누어 물리적 메모리에 올리는 기법

코드, 데이터, 스택 등의 의미 있는 단위로 주소 공간을 나눈 것

크기가 균일하지 않아 부가적인 관리 오버헤드가 발생한다.

<세그먼트 번호(논리적 주소가 프로세스 주소 공간 내에서 몇 번째 세그먼트인지), 오프셋(그 세그먼트에서 얼마나 떨어져 있는지)>

  • 세그먼트 테이블

    • 기준점

      물리적 메모리에서 세그먼트의 시작 위치

    • 한계점

      그 세그먼트의 길이

    • 세그먼트 테이블 기준 레지스터 STBR

      현재 CPU에서 실행 중인 프로세스의 세그먼트 테이블이 메모리의 어느 위치에 있는지 시작 주소

    • 세그먼트 테이블 길이 레지스터 STLR

      프로세스의 주소 공간이 총 몇 개의 세그먼트로 구성되는지, 개수

    • 보호비트

    • 유효-무효비트

  1. STLR에 저장된 값보다 작은 값인가
  2. 논리적 주소의 오프셋값이 그 세그먼트의 길이보다 작은 값인가

두가지를 만족해야 주소 변환 가능

  • 공유 세그먼트

공유와 보안의 측면에 서 효과적, 외부조각 발생, 어느 가용 공간에 할당할지 문제 -> 최초/최적

스크린샷 2021-08-10 오전 2 10 53


6. 페이지드 세그멘테이션

페이징, 세그멘테이션의 장점만 취하는 주소 변환 기법

세그먼트가 동일한 크기 페이지들의 집합으로 구성 -> 외부조각 해결

외부의 세그먼트 테이블과 내부의 페이지 테이블로 2단계 페이지 테이블 구성

<세그먼트 번호, 오프셋>

  1. 세그먼트 번호를 통해 세그먼트 테이블 항목(세그먼트 길이, 페이지 테이블 시작 주소) 접근

  2. 세그먼트 길이값과 오프셋값 비교

  3. 오프셋값을 상위 하위로 나누어 상위는 세그먼트 내 페이지 번호, 하위는 페이지 내 변위로 사용

  4. 페이지 내 변위만큼 떨어진 페이지 테이블 항목으로부터 물리적 메모리의 페이지 프레임 위치 얻는다.

    스크린샷 2021-08-10 오전 2 16 02o