Memory

🗓️

메모리 관리

  • 프로세스에게 메모리를 할당하는 방법
  • 컴퓨터 시스템에서 페이징의 동작 방법

배경

  • 메모리는 각각 주소가 할당된 이련의 바이트들로 구성된다.
  • CPU는 프로그램 카운터가 지시하는 대로 메모리로부터 다음 명령어를 가져온다.
  • 명령어는 필요한 경우 추가적인 데이터를 더 가지고 올수도 있고 내보낼 수도 있다.

기본 하드웨어

  • 메인 메모리와 프로세서 자체에 내장되어 있는 레지스터들은 CPU가 직접 접근할 수 있는 유일한 범용 저장장치다.
  • 어셈블리 메모리 주소만을 인수로 취하고, 디스크의 주소를 인수로 취하지 않는다.
  • 실행되는 명령어와 데이터들은 CPU가 직접적으로 접근할 수 있는 메인 메모리와 레지스터에 있어야 한다.
  • 데이터가 메모리에 없다면 CPU가 그것들을 처리하기 전에 메모리로 이동시켜야 한다.
  • 레지스터들은 일반적으로 CPU클록의 1사이클 이내에 접근가능하다
  • 메모리 버스를 통해 전송되는 메인 메모리의 경우 접근을 완료하기위해 많은 CPU사이클이 소요되며, 이 경우 필요한 데이터가 없어 멈춤 현상이 발생하게 된다.
    • 해결 방법은 CPU와 메인 메모리 사이에 빠른 속도의 메모리를 추가하는 것이다 (캐시)
  • 물리 메모리의 상대적인 접근 속도 차이를 고려하는 것에 추가로 올바른 동작을 보장해야만 한다.
    • 시스템이 올바르게 동작하기 위해서는 사용자 프로그램으로부터 운영체제 영역을 보호해야 한다.
    • 다중사용자 시스템인 경우 추가적으로 다른 사용자 프로그램이 특정 사용자 프로그램을 접근하는것을 막는것도 함께 이뤄져야 한다.
  • 각각의 프로세스가 독립된 메모리 공간을 가지도록 보장해야 한다.
  • 개별적인 메모리 공간을 분리하기 위해 특정 프로세스만 접근할 수 있는 주소 영역을 설정하고 그 영역만 접근제어를 해야한다.
  • 메모리공간의 보호는 CPU하드웨어가 사용자 모드에서 만들어진 모든 주소와 레지스터를 비교함으로써 이루어진다.
  • 이를 무시하고 권한이 다른 영역으로 접근하는 순간 트랩을 발생시킨다.
  • 운영체제만 레지스터들의 값을 변경할 수 있다.
  • 커널 모드에서 수행되는 운영체제는 이러한 접근제어의 제약을 받지 않는다.
    • 멀티 프로세서 시스템 운영체제는 한 프로세스의 상태를 레지스터로부터 메인 메모리로 저장하고 다음 프로세스의 컨텍스트를 메인 메모리로부터 레지스터로 저장하는 컨텍스트 스위칭을 반드시 실행해야 한다.

주소의 할당

  • 프로그램은 바이너리 형태로 디스크에 저장되어 있다. 이 프로그램이 실행되기 위해서는 메인메모리로 올라와서 프로세스가 되어야 한다. 디스크에서 메인메모리로 들어오기를 기다리고 있는 프로세스들의 집합을 입력 큐를 이룬다.
  • 단일 태스킹의 작업 절차는 이 입력 큐의 프로세스 중 하나를 선택해서 메모리로 적재한다. 이 프로세스는 실행 중에 메모리에서 명령어와 데이터를 억세스 한다.
  • 사용자 프로그램이 적재되는 과정
    • 원시 프로그램에서 주소는 숫자가 아닌 심볼 형채로 표현된다.
    • 컴파일러는 이 심볼 주소를 재배치 가능 주소로 바인딩 시키고
    • 추후에 연결 편집기나 로더가 이 재배치 가능주소를 절대주소로 바인딩 시킨다.
    • 각각의 바인딩 과정은 한 주소 공감에서 다른 주소공간으로 매핑하는 것이다.
  • 메모리 주소 공간에서 명령어와 데이터와 바인딩의 구분
    • 컴파일 시간 바인딩 : 컴파일 시점에 적재될 메모리 위치를 미리 알 수 있으면 컴파일러는 절대코드를 생성할 수 있다.
    • 로딩 시간 바인딩 : 로딩 될 위치를 알 수 없으면 바이너리를 재배치 가능 코드로 만든다. 이 경우 심볼과 주소의 바인딩은 프로그렘이 메인 메모리로 로딩되는 시점에 이루어진다.
    • 실행 시간 바인딩 : 프로세스가 실행되는 중 메모리 내의 다른 세드먼트로 옮겨질 수 있다면 바인딩이 실행시간까지 허용됐다고 한다.

논리 대 물리 주소 공간

  • 논리 주소 (aka 가상 주소) : CPU가 생성하는 주소
  • 물리 주소 (aka 메모리 주소 레지스터) : 메모리가 취급하는 주소
  • 논리 주소 공간 : 프로그램에 의해 생성된 모든 논리 주소 집합
  • 물리 주소 공간 : 논리 주소와 일치하는 모든 물리 주소 집합
  • 메모리 관리기 MMU : 프로그램 실행중에는 가상 주소를 물리 주소로 바꾸는데 필요한 하드웨어 장치
  • 재배치 레지스터 (aka 기준 레지스터) : 주소가 메모리로 보내질 때 마다 그 모든 주소에 더해지는 값
  • 사용자 프로그램은 실제 물리 주소를 알 수 없다. (기준레지스터에 대해 다시 바인딩 되기 때문)

동적 로딩

  • 메모리 공간의 효율적 이용을 위해 동적 로딩을 해야 한다.
  • 실제 호출 되기 전까지 메모리에 올라오지 않고 재배치 가능한 상태로 디스크에서 대기한다. 호출될때 재배치 링킹 로더가 호출되 요구된 루틴을 메모리로 가져오고 이러한 변화를 테이블에 기록한다.
  • 동적 로딩의 장점은 루틴이 필요한 경우에만 적재된다.

동적 링킹 및 공유 라이브러리

  • 사용자 프로그램이 실행될 때, 프로그램에 연결되는 시스템 라이브러리다.
  • 동적 링킹 개념은 동적 로딩 개념과 유사하다
  • 동적 로딩에서는 로딩이 실행까지 미루어졌었지만 동적 링킹에서는 링킹이 실행 시기까지 미뤄지는 것이다.
  • 동적 링킹은 주로 시스템 라이브러리에 사용된다.
    • 만약 이 방식이 없으면 모든 시스템 라이브러리를 호출하는 프로그램들은 바이너리 이미지 내에 시스템 라이브러리 루틴을 한부씩 가지고 있어야만 한다.
  • 동적 링킹에서는 라이브러리를 부르는 곳 마다 stub이 생긴다.
    • stub은 라이브러리를 어떻게 찾을것인가 알려주는 작은 코드 조각이다.
  • stub이 실행 될 때, stub은 필요한 라이브러리 루틴이 이미 메모리에 존재하는가 검사한다. 없으면 디스크에서 가져온다. 둘 중의 어느 방식으로 하든 stub은 이렇게 해서 그 라이브러리의 루틴이 번지수를 알아내게 되고 그 자신을 그 루틴의 번지로 대체하게 된다. 다음번에 그 부분이 불리면 이와 같은 동적 링킹을 할 필요가 없이 직접 그곳의 라이브러리 루틴을 수행하면 된다. 이러한 구조 하에서는 같은 라이브러리를 10개의 프로세스가 사용하더라도 라이브러리 코드는 한개만 있으면 된다.
  • 동적 링킹이 없었다면 새로운 라이브러리를 사용하기 위해 모든 프로그램은 새로 링크되야 한다.
  • 공유 라이브러리 : 라이브러리는 어느때나 새로운 버전으로 교체될 수 있고 그렇게 되면 그 라이브러리를 사용하는 모든 프로그램은 자동적으로 이 새로운 라이브러리 버전을 사용하게 된다. 이런 시스템을 일컫는 말.
  • 동적 로딩과 달리 동적 링킹과 공유 라이브러리는 운영체제의 도움이 필요하다. 운영체제만 라이브러리 루틴이 메모리에 있는지 검사할 수 있다. 페이징에서 확장되는 개념이다.

Swapping

  • 프로세스가 실행되기 위해서는 메모리에 있어야 하지만 프로세스는 실행 중에 임시로 예비 저장장치로 스왑되었다가 실행을 위해 다시 메모리로 돌아올 수 있다.
  • 모든 프로세스의 물리 주소 공간의 크기의 총합이 시스템의 실제 물리 메모리크기보다 큰 경우에도 스왑을 이용하면 동시에 실행하는 것이 가능하다.

기본 스왑

  • 기본 스왑은 메인 메모리와 예비 저장장치 사이에서 프로세스를 이동시킨다.
  • 이 저장장치의 크기는 모든 사용자의 메모리 이미지를 저장할 수 있을 만큼 커야 하며 이 메모리 이미지에 대한 직접적인 접근이 가능해야 한다.
    • 시스템은 준비된 프로세스들을 모아 준비완료 큐에 가지고 있는다.
    • CPU스케줄러는 다음 프로세스를 고를 때 디스패처를 호출한다. 다음 프로세스가 메모리에 없다면 디스크에서 불러들인다.
    • 다음 프로세스를 위한 공간이 충분하지 않다면 현재 메모리에 올라와있는 프로세스를 스왑 아웃하고 원하는 프로세스를 불러들인다.
    • CPU의 모든 레지스터를 실행해야 할 프로세스로 다시 로딩하고 제어를 넘긴다.
  • 이런 스왑 시스템은 컨텍스트 스위칭 시간이 매우 오래 걸린다. 스왑 시간의 대부분은 디스크 전송 시간이 차지한다.
  • 스왑에는 다른 제약이 있다. 한 프로세스를 스왑하기 원한다면 완전히 suspend상태에 있음을 확인해야 한다.
  • 변형 스왑 : 시스템 메모리가 부족하면 작동을 시작한다.

연속 메모리 할당

  • 메모리는 일반적으로 두개의 부분으로 나뉜다
    • 메모리에 상주하는 운영체제를 위한 부분
    • 사용자 프로세스를 위한 부분
  • 인터럽트 백터는 흔히 0번지에 위치해 운영체제는 하위 메모리에 위치시키는 것이 일반적이다.
  • 여러 프로세스가 동시에 메모리에 올라와있는것이 바람직하기 때문에 메모리에 올라오고자 입력 큐에서 기다리고 있는 프로세스들에게 메모리를 얼만큼 할당하는것이 좋을까 생각할 필요가 있다.
  • 연속 메모리 할당 시스템에서는 각 프로세스는 다음 프로세스를 포함하는 영역과 연속된 하나의 메모리 영역을 차지하게 된다.

메모리 보호

  • 시스템이 상한 레지스터와 재배치 레지스터를 가지고 있다면 메모리 접근을 강제할 수 있다.
  • 재배치 레지스터는 가장 작은 물리 주소값을 저장하고, 상한 레지스터는 논리주소의 범위 값을 저장한다.
  • MMU는 논리 주소에 재배치 레지스터 값을 더해 주소를 변환하는 역할을 한다.
  • CPU스케줄러가 다음으로 수행할 프로세스를 선택할 때, 디스패처는 컨텍스트 스위치의 일환으로 재배치 레지스터와 상한 레지스터에 정확한 값을 적재한다.
  • CPU에 의해서 생성되는 모든 주소들은 이 레지스터 값을 참조해서 확인 작업을 거치기 때문에, 운영체제와 다른 사용자 프로그램의 접근제어가 가능하다.
  • 재배치 레지스터를 사용함으로써 운영체제의 크기는 실행 중이라도 변경 된다.

메모리 할당

  • 간단한 공간 할당 방법은 메모리를 똑같은 고정된 크기로 분할 하는 것이다. 현재는 사용되지 않는다.
  • MVT : 배치 환경에서 고정된 크기의 분할 영역을 사용하는 방법이다.
  • 가변 분할 : 운영체제는 메모리의 사용 유무를 파악하는 테이블을 유지한다. 포기에 모든 메모리 공간은 한개의 사용 가능한 블록으로 간주된다.
  • 메모리는 다양한 크기의 공간의 집합을 포함하게 된다.
  • 일반적으로 메모리에는 다양한 크기의 자유 공간이 여기저기 산재하게 된다. 프로세스가 공간을 필요로 할 떄 운영체제는 이 공간 중에서 적절한 것을 찾아내야 한다.
  • 동적 메모리 할당 문제에 대한 해결책
    • 최초 적합 : 첫번째 사용 가능한 가용공간을 할당한다.
    • 최적 적합 : 사용가능한 공간들 중에서 가장 작은것을 택한다.
    • 최악 적합 : 가장 큰 가용 공간을 택한다.
  • 시뮬레이션을 통해서 최초 적합과 최적 적합이 최악적합보다 좋다는 것이 입증되었다.

단편화

  • 외부 단편화 : 프로세스들이 메모리에 로딩되고 제거되는 일이 반복되다 보면 어떤 공간은 너무 작은 조각이 되어 버린다. 유휴공같을 모두 합치면 충분한 공간이 되지만 그것이 너무 작은 조각들로 여러곳에 분산되어 있을 때 발생한다.
  • 메모리 전체 크기와 프로세스 크기는 모두 외부 단편화에 따라 중요한 영향을 미칠 수 있다.
  • 내부 단편화 : 65536바이트의 공간이 있다. 프로세스가 65534 바이트를 요구한다고 가정할때, 블록을 정확히 할당하면 2바이트의 가용 공간이 남는다. 이런경우 2바이트짜리 가용공간을 놓치지 않기 위해 시스템은 2바이트보다 더 큰 오버헤드를 가진다. 따라서 일반적으로 메모리를 먼저 아주 작은 공간들로 분할하고 프로세스가 요청하면 할당을 항상 이 분할된 크기의 정수 배로만 해주는 것이 보통이다. 이 경우 할당된 공간은 요구된 공간보다 약간 더 클 수 있다. 이들 두 크기 사이의 남는 부분이 바로 내부 단편화다.
  • 외부단편화의 해결방법
    • 메모리의 모든 내용을 한군데로 몰고 모든 빈공간들을 다른쪽으로 몰아서 큰 블록을 만드는것 → 재배치가 로딩시에 정적으로 이루어지면 불가능하다. 동적으로 이루어지는 경우에만 가능.
    • 한 프로세스의 논리 주소 공간을 여러개의 비연속적인 공간으로 나눠 필요한 크기의 공간이 사용가능해지는 경우 물리 메모리를 프로세스에게 할당하는 방법. (페이징, 세그멘테이션)

세그멘테이션

  • 사용자가 인식하는 메모리의 모습은 실제 물리 메모리의 모양과 같지 않다.
  • 세그멘테이션은 인지하는 메모리의 모습을 실제 물리 메모리의 모습으로 변환하는 기법이다.

기본 방법

  • 논리 주소 공간은 세그먼트들의 집합으로 이루어진다.
  • 각 세그먼트는 이름과 길이를 가진다.
  • 프로그램에서 사용되는 주소는 세그먼트의 이름과 세그먼트 내의 오프셋을 모두 명시한다.
    • 구현을 위해 세그먼트 이름 대신 논리주소에 따라 세그먼트 번호가 매겨진다.
  • 세그멘테이션의 구조
    1. 코드
    2. 전역변수
    3. 스택
    4. libc

하드웨어

  • 프로그래머는 세그먼트를 2차원 주소로 지정할 수 있지만(상대주소) 물리주소는 1차원의 주소다.
  • 세그먼트 테이블에 의해 2차원 주소가 1차원 물리 주소로 매핑된다.
  • 세그먼트 테이블의 항목
    • 세그먼트 기준 : 세그먼트의 시작 주소
    • 세그먼트 상한 : 세그먼트의 길이를 명시

페이징

  • 세그멘테이션은 프로세스가 로딩되는 물리 주소 공간이 연속적이지 않아도 적재를 허용한다.
  • 페이징은 이러한 이점을 제공하는 메모리 관리기법이다.
  • 페이징은 외부 단편화를 방지하고 단편화에 따른 압축 작업이 필요없다.
    • 세그멘테이션은 그렇지 않다.
  • 페이징은 스왑 아웃되는 세그먼트를 예비 저장장치에 저장해야 하는 문제도 해결한다.

기본 방법

  • 물리 메모리프레임이라 불리는 같은 크기의 블록으로 나눈다.
  • 논리 메모리페이지라 불리는 같은 크기의 블록으로 나눈다.
  • 프로세스가 실행 될 때 페이지는 파일 시스템 또는 예비 저장장치로부터 가용한 메인 메모리 프레임으로 적재된다.
  • 예비 저장장치는 메모리 프레임 혹은 묶음인 클러스터와 같은 크기의 크기가 고정된 블록으로 나눈다.
    • 이렇게 하면 논리주소공간은 물리주소공간으로부터 완전히 분리할 수 있어 물리주소 크기로 부터 독립된 논리주소를 사용할 수 있다.
  • 페이지 테이블 : 메인 메모리에서 각 페이지가 점유하는 주소를 갖고 있다.
  • 페이지 번호 (p) : 페이지 테이블을 액세스 할 때 사용된다.
  • 페이지 오프셋 (d) : 물리주소 매핑을 위한 오프셋
  • 페이징 자체는 동적 재배치의 한 형태다. 모든 논리 주소는 페이징 하드웨어에 의해 물리 주소로 매핑된다.
  • 페이징 기법을 사용하면 외부 단편화가 발생하지 않는다.
    • 하지만 내부 단편화가 발생한다.
    • 내부 단편화를 방지하기 위해 페이지 크기를 줄이면 테이블의 크기로 인해 낭비된다.
  • 한 프로세스가 실행되기 위해 도착하면 그 프로세스의 크기를 페이지 단위로 계산한다.
  • 각 사용자 페이지는 한 프레임씩을 필요로 한다.
  • 프로세스의 처음 페이지가 할당된 프레임들 중 하나에 로딩되고, 그 프레임 번호가 페이지 테이블에 기록된다. 그리고 테이블에 기록되는 과정이 반복된다. 페이징의 가장 중요한 특징은 메모리에 대한 프로그래머의 인식과 실제 내용이 서로 다르다는 것이다. 프로그래머는 메모리가 하나의 연속적인 공간이며, 메모리는 이 프로그램만 있다고 생각한다. 그러나 실제로는 프로그램은 여러곳에 프레임 단위로 분산되어 있고 많은 다른 프로그램이 올라와있다. 프로래머가 생각하는 메모리와 실제 물리 메모리의 차이는 주소 변환 하드웨어에 의해 해소된다. 논리 주소는 물리 주소로 변환된다. 이 매핑은 프로그래머에게는 안보이고 운영체제에 의해 조정된다. 따라서 사용자 프로세스는 자기의 것이 아닌 메모리는 접근조차 할 수 없다. 페이지 테이블을 통하지 않고서는 다른 공간을 접근할 길이 없으며 페이지 테이블은 그 프로세스가 소유하고있는 페이지들만 가리키고 있기 때문이다.
  • 프레임 테이블 : 운영체제가 관리하는 물리 메모리의 할당에 대한 자세한 정보 테이블. 할당된 프로세스, 사용가능한 프레임 갯수 등을 관리한다.

하드웨어 지원

  • 가장 간단한 페이지 테이블은 레지스터의 집합으로 구현된다.
  • 레지스터는 페이징 주소변환을 효율적으로 하기 위해 고속 논리 회로로 설계된다.
  • 메모리의 모든 엑세스는 이 페이징 맵을 통해야 하므로 매핑의 효율은 매우 중요하다.
  • 페이지 테이블 레지스터를 채우는 일은 특수한 명령이기 때문에 운영제체만 할 수 있다.
  • 페이지 테이블 기준 레지스터 PTBR : 페이지 테이블을 메인 메모리에 저장하고 페이지 테이블을 가리키도록 하는 레지스터.
    • 이 방식의 문제점은 메모리 접근 시간이다
  • PTBR의 느린 메모리 접근 시간에 대한 해결로 TLB(Translation Look-aside Buffers) 캐시가 사용된다.
  • TLB는 매우 빠른 associate 메모리로 구성된다. TLB는 key-value 로 구성된다.
    • TLB는 속도를 위해 작게 유지된다.
  • 만약 페이지 번호가 메모리에서 찾아지지 않으면 페이지 테이블을 접근하기 위한 메모리 참조가 일어난다.
  • ASID (Address-space identifiers) : TLB 항목이 어느 프로세스에 속한것인지 알려주며 그 프로세스의 정보를 보호하기 위해 사용된다. TLB는 하드웨어 구성요소이고 따라서 운영체제와 그 설계자들에게는 영향을 주지 않을 것처럼 보인다. 그러나 설계자들은 TLB의 기능과 구성요소를 이해해야 하며 이러한 것들은 하드웨어 플랫폼에 따라 달라진다. 최적의 동작을 위해서 주어진 플랫폼을 위한 운영체제 설계는 그에 따른 페이징을 구현해야 한다. 마찬가지로 TLB 설계의 변경은 이를 사용하여 운영체제가 구현하는 페이징 방법을 바꾸게 만든다.

보호

  • 페이지화된 환경에서 메모리 보호는 각 페이지에 붙어있는 보호비트에 의해 구현된다.
    • 보호 비트는 페이지 테입르에 속해있다.
    • 보호 비트는 페이지가 RW또는 Read-only로 각각 정의할 수 있다.
  • 메모리에 대한 모든 접근은 페이지 테이블을 거치므로 이때 주소 변환과 함께 이 페이지에 쓰기 허용 여부를 검사할 수 있다.
  • 읽기 전용 페이지에 대해 쓰기를 시도하면 운영체제가 하드웨어로 trap을 걸어준다.
  • 페이지 테이블 엔트리에는 valid/invalid 비트가 더 있다. 운영체제는 이 비트를 사용해 페이지에 대한 접근제어를 한다.
    • valid로 설정되면 관련된 페이지가 프로세스의 합법적인 페이지임을 나타낸다.
    • invalid로 설정되면 그 페이지는 프로세스의 논리 주소 공간에 속하지 않는다는 것을 나타낸다.
  • 페이지 테이블 길이 레지스터 (Page Table Length Register) : 모든 페이지에 페이지 테이블 항목을 배정하는것을 방지하기 위해 페이지 테이블의 크기를 나타내기 위한 레지스터. 프로세스가 제시한 주소가 유효한 범위 내에 있는지를 확인하기 위해 모든 논리주소값이 PTLR값과 비교된다.

공유 페이지

  • 시분할 환경에서 페이징의 장점은 코드를 쉽게 공유할 수 있다는 점이다.
  • 재진입 가능 코드 일 때 아래와 같이 프로그램을 공유할 수 있다.
  • 재진입 가능 코드는 수행하는 동안 변할 수 없다. 그래서 동시에 같은 코드를 수행할 수 있다. 이 때 코드 부분은 서로 공유하더라도 각각의 프로세서들은 레지스터들의 복사 값과 프로세스가 수행되는 동안 필요한 데이터들을 저장하는 데이터 저장소를 따로 가지고 있다.
  • 시스템에서 프로세스들 사이의 메모리 공유는 4장 스레드에서 주소공간 공유와 유사하다. 3장의 프로세스간 통신에서 메모리 공유가 사용된다.
  • 페이지를 통한 메모리 관리는 같은 물리 페이지 프레임을 여러 프로세스가 공유한다.

페이지 테이블의 구조

  • 논리주소 공간이 너무 크다. 어떻게 관리하면 좋을까?

계층적 테이블

  • 2레벨의 페이지테이블
  • 논리주소 공간을 여러개로 추상화 한다.

해시 페이지 테이블

  • 32비트보다 주소가 크다면 해싱을 이용해 페이지 테이블을 관리하자 (virtual address table 개념)

역 페이지 테이블

  • PID가 어떤 페이지 테이블을 갖고 있는가 / 페이지 테이블을 역으로 관리한다

summary

  • 다음은 메모리 관리 정책들을 비교하는데 중요한 관점들이다.
  • 하드웨어 지원 : 페이징과 세그멘테이션은 mapping table이 필요하다.
  • 성능 : 구조가 복잡해질 수록 논리주소를 물리 주소로 변환하는 비용이 커진다. 페이징과 세그멘테이션도 mapping table의 빠른 작동을 위해 TLB 캐시를 제공하면 성능이 향상될 수 있다.
  • 단편화 : 페이징과 같이 고정된 크기의 할당 단위를 가진 시스템은 내부 단편화의 문제가 있다. 세그멘테이션과 같은 가변할당 단위를 가진 시스템은 외부 단편화 문제를 가지고 있다.
  • 재배치 : 외부 단편화에 대한 문제 해결중 하나는 압축이다. 압축은 메모리 영역을 한쪽 끝으로 옮기는것이다. 주소가 로딩 시간에 재배치되고 결정된다면 압축이 불가능 하다.
  • 스왑 : 프로세스를 메모리에서 예비 저장장치로, 그 반대로 이동시키는 기법.
  • 공유 : 다중 프로그래밍의 정도(degree)를 증대시킬수 있는 방법은 코드와 데이터를 공유하게 하는 것이다. 페이징과 세그멘테이션 기법을 필요로 한다.
  • 보호 : 페이지나 세그먼트 각 부분들이 실행전용, 읽기전용, 읽기쓰기 등으로 선언될 수 있다. 접근제어를 사용하여 시스템과 사용자 정보를 보호한다.