메모리 관점에서 보면, 초기에 사용자들에게 많은 추상화를 제공하지 않았다. 메모리는 사진에 보이는 것과 비슷했다.

OS는 메모리에 있는 루틴의 집합(라이브러리)
비싼 기계를 효율적으로 쓰기 위해 다중 프로그래밍이 탄생했다. 여러 프로세스가 실행 준비가 되며, OS가 그들을 전환했다. 이후에, 타임 쉐어링도 나오고 배치 컴퓨팅의 한계를 깨달았다.
타임쉐어링을 구현하는 한 가지 방법은 짧은 시간 동안 한 프로세스를 실행하고, 모든 메모리에 대한 엑세스 권한을 부여한 다음 멈추고, 어떤 디스크에 저장하고, 다른 프로세스를 로드하는 것이다.
여기서 메모리의 내용을 디스크에 저장,복원하는 것은 굉장히 느리다. 따라서 메모리에 프로세스를 남겨두면서 OS가 효율적으로 타임 쉐어링을 구현하도록 해야한다.

사진의 다이어그램에는 세 개의 프로세스(A,B,C)가 있고, 각각 512KB의 메모리에서 부분을 할당받는다. 단일 CPU일 떄 OS는 프로세스중 하나를 실행하고, 나머지는 실행대기열에서 실행을 기다린다. 이때, 실행중인 프로세스가 다른 프로세스의 메모리를 읽고 쓸 수 있는 상황은 달가운 상황이 아니다.
OS는 실제 메모리를 추상화한다. 그것을 address space라고 한다.
프로세스의 address space에는 실행중인 프로그램의 모든 메모리 상태가 포함된다.
address space 에는 코드,스택,힙이 포함된다.
프로그램 코드는 메모리에 있어야하므로 address space에 있다.
또, 프로그램은 스택을 사용하여 함수 호출 체인에서 위치를 추적하고, 지역 변수 할당, 매개 변수 전달등을 한다.
마지막으로, 동적으로 할당되는 힙을 사용하여 사용자 관리 메모리로 쓸 수 있다.
아래 사진은 16KB의 address space를 할당하여 코드,스택,힙을 구성한 모습이다. 힙은 코드의 바로 다음에서, 스택은 address space의 마지막에서 시작한다.

address space 16KB를 할당받았다해도, 실제 메모리 16KB에 있다는 뜻은 아니다. 실제로 프로그램들은 메모리의 서로 다른 주소에 로드되어 있다.
예를 들어 address space 0KB에 접근하려할 때 실제 메모리 320KB(실제 저장된 주소)에 접근하도록 하는 것이 OS가 실제로 메모리를 가상화하는 방법이다.
가상메모리(VM)의 목표 중 하나는 투명성 transparency이다. OS는 가상 메모리를 실행 중인 프로그램에게 보이지 않게 구현해야하며, 따라서 프로그램은 메모리가 가상화 되었다는 것을 알지 못한다.
또 다른 목표는 효율성 efficiency이다. 프로그램이 빨리 구동되고, 많은 메모리를 쓰지 않도록 효율적으로 가상화 해야한다. 시간 효율적인 구현을 위해 하드웨어에 의존해야한다. 나중에 알게 될 TLB와 같은 하드웨어 기능이 도움을 줄 수있다.
마지막 목표는 보호 protection이다. 각 프로세스는 load,store,fetch 등을 수행할 때 다른 프로세스나 OS의 메모리에 영향을 줄 수 없어야 한다.
THE PRINCIPLE OF ISOLATION 격리의 원칙
격리는 신뢰할 수 있는 시스템을 구축하는데 중요한 원칙이다.
두 개체가 서로 격리되어 있으면, 서로 영향을 주지 않는다.
OS는 메모리 격리를 유지하여 서로 다른 프로세스에게 해를 끼치지 않도록 한다.
일부 현대 OS는 격리를 더 강화하기 위해 OS의 일부를 다른 OS의 일부와 격리한다.
이런 마이크로커널은 일반 단일체 커널 설계보다 더 높은 신뢰성을 제공할 수 있다.
C 프로그램에서 포인터를 출력해본적이 있는가? 주소로 출력되는 값은 가상주소이다. 프로그램의 코드 주소를 출력해도 그것은 가상 주소이다. 실제로 사용자 수준 프로그램으로 볼 수 있는 모든 주소는 가상 주소이다.
메모리를 가상화하는 OS만이 실제 주소를 알 수 있다.
다음은 코드,힙,스택 주소(가상의)를 출력하는 프로그램이다.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("location of code : %p\n", main);
printf("location of heap : %p\n", malloc(100e6));
int x = 3;
printf("location of stack: %p\n", &x);
return x;
}
결과를 보면 코드,힙,스택의 순서로 위치해있다는 것을 알 수 있다.
location of code : 0x1095afe50
location of heap : 0x1096008c0
location of stack: 0x7fff691aea64