가상 메모리(virtual memory)는 프로그램이 쓰는 논리 주소(logical address)와 주기억장치의 실제 자리인 물리 주소(physical address)를 갈라 두고, 프로그램을 조각내어 주기억장치 곳곳에 흩어 놓거나 일부만 올려 둔 채 실행하게 하는 기법입니다. 프로그램 전체를 한 영역에 넣을 때 생기던 단편화와, 주기억장치보다 큰 프로그램을 돌리지 못하던 한계를 함께 덜어 줍니다.
기억장치 배치와 단편화에서는 프로그램 하나를 통째로 한 영역에 넣었습니다. 그러면 프로그램보다 큰 빈 영역을 찾아야 하고, 넣고 나면 빈칸이 남습니다. 프로그램을 조각으로 나누면 조각마다 빈자리 어디에나 넣을 수 있습니다. 대신 프로그램이 주소를 쓸 때마다 표를 보고 실제 주소로 바꿔야 합니다. 아래 그림은 논리 주소가 페이지 번호와 오프셋으로 나뉘어 페이지 표를 거쳐 물리 주소가 되는 과정과, 세그먼트 표로 주소를 바꾸는 과정을 보입니다.
1페이징 — 페이지 번호와 오프셋
페이징(paging)은 프로그램을 같은 크기의 페이지(page)로, 주기억장치를 같은 크기의 프레임(frame)으로 나눕니다. 페이지는 빈 프레임 어디에나 들어갑니다. 그림에서는 둘 다 1KB(1,024바이트)입니다.
논리 주소를 페이지 크기로 나누면 몫이 페이지 번호이고, 나머지가 그 페이지 안의 자리인 오프셋(offset)입니다. 자료에 따라 오프셋을 변위라고도 부릅니다. 페이지 크기를 1,024처럼 2의 거듭제곱으로 잡으면 주소의 아래 10비트가 그대로 오프셋이 됩니다.
페이지 표(page table)는 페이지마다 들어 있는 프레임 번호를 적어 둔 표입니다. 자료에 따라 페이지 테이블·페이지 맵 테이블이라고도 부릅니다. 페이지 번호로 표를 찾아 프레임 번호로 바꾸고, 오프셋은 그대로 붙이면 물리 주소입니다.
- 물리 주소 = 프레임 번호 × 페이지 크기 + 오프셋
- 논리 주소 2100 → 2100 ÷ 1024 = 2 … 52 → 페이지 2는 프레임 5 → 5 × 1024 + 52 = 5172
표에 프레임이 적혀 있지 않으면 그 페이지는 아직 디스크에 있습니다. 이것을 페이지 부재(page fault)라 합니다. 운영체제가 그 페이지를 빈 프레임에 올리고 표를 고친 뒤 주소를 다시 바꿉니다. 쓰는 페이지만 그때그때 올리므로 프로그램 전체가 주기억장치에 없어도 실행됩니다.
2세그먼테이션 — 시작 주소와 길이
세그먼테이션(segmentation)은 프로그램을 코드·데이터·스택처럼 뜻이 있는 단위로 나눕니다. 이 조각을 세그먼트(segment)라 하고, 세그먼트마다 크기가 다릅니다.
논리 주소는 세그먼트 번호와 오프셋입니다. 세그먼트 표에는 세그먼트마다 주기억장치의 시작 주소와 길이가 적혀 있습니다. 오프셋이 길이보다 작으면 시작 주소에 더해 물리 주소를 얻고, 길이를 넘으면 남의 자리를 건드리지 않게 오류로 막습니다.
| 가르는 기준 | 페이징 | 세그먼테이션 |
|---|---|---|
| 나누는 단위 | 같은 크기의 페이지 | 뜻 단위의 세그먼트 |
| 표에 적는 것 | 프레임 번호 | 시작 주소와 길이 |
| 물리 주소 | 프레임 번호 × 페이지 크기 + 오프셋 | 시작 주소 + 오프셋 |
| 생기는 단편화 | 내부 단편화 | 외부 단편화 |
페이지는 크기가 같아 빈 프레임 어디에나 빈틈없이 들어가므로 외부 단편화가 없습니다. 다만 프로그램 크기가 페이지 크기로 나누어떨어지지 않으면 마지막 페이지 안이 남습니다. 2,500바이트 프로그램은 1KB 페이지 셋을 쓰고, 셋째 페이지에 572바이트가 남습니다. 세그먼트는 크기가 달라 들고 나기를 거듭하면 그 사이에 작은 빈틈이 흩어집니다.
3페이지 크기가 작을 때와 클 때
페이지를 작게 나누면 쓰는 부분만 촘촘히 올릴 수 있지만 페이지 수가 늘어납니다. 크게 나누면 그 반대입니다.
| 가르는 기준 | 페이지가 작을 때 | 페이지가 클 때 |
|---|---|---|
| 페이지 표 크기 | 커진다(페이지가 많다) | 작아진다 |
| 내부 단편화 | 작다 | 크다 |
| 쓰지 않을 내용까지 올라옴 | 적다 | 많다 |
| 디스크를 읽는 횟수 | 많다 | 적다 |
예제
그림의 페이지 표(페이지 0·1·2·3 → 프레임 3·7·5·없음, 페이지 1KB)와 세그먼트 표(1번 세그먼트: 시작 4000, 길이 300)로 주소를 바꿉니다.
| 논리 주소 | 거치는 길 | 물리 주소 |
|---|---|---|
| 2100 | 2100 ÷ 1024 = 2 … 52 → 페이지 2는 프레임 5 | 5 × 1024 + 52 = 5172 |
| 3500 | 3500 ÷ 1024 = 3 … 428 → 페이지 3은 표에 없음(페이지 부재) → 빈 프레임 1에 올림 | 1 × 1024 + 428 = 1452 |
| (1, 120) | 세그먼트 1, 오프셋 120은 길이 300보다 작음 | 4000 + 120 = 4120 |
| (1, 350) | 오프셋 350이 길이 300을 넘음 | 주소 오류 |
시험 포인트
- 필기: 페이징의 논리 주소는 페이지 번호와 오프셋이고, 페이지 표가 페이지 번호를 프레임 번호로 바꿉니다(물리 주소 = 프레임 번호 × 페이지 크기 + 오프셋). 표에 없는 페이지를 쓰면 페이지 부재입니다. 세그먼테이션은 시작 주소에 오프셋을 더하고, 오프셋이 길이를 넘으면 오류입니다. 페이징은 내부 단편화, 세그먼테이션은 외부 단편화가 생깁니다. 페이지가 작으면 페이지 표가 커지고 내부 단편화가 줄며 디스크를 읽는 횟수가 늘어납니다. 주소 계산과 '페이지가 작을 때 일어나는 일' 고르기로 나옵니다.
- 실기: 이름은 가상 메모리(Virtual Memory), 페이징(Paging), 세그먼테이션(Segmentation), 페이지 부재(Page Fault)로 씁니다.
확인 문제
1. 같은 프로그램에서 페이지 크기를 4KB에서 1KB로 줄였습니다. 그 결과로 알맞은 것을 고르세요.
- ① 페이지 표의 행 수가 줄어든다.
- ② 마지막 페이지 안에 남는 칸이 줄어든다.
- ③ 디스크에서 페이지를 읽어 오는 횟수가 줄어든다.
- ④ 페이지 사이에 외부 단편화가 생긴다.
정답
②입니다. 페이지가 작을수록 마지막 페이지에 남을 수 있는 칸도 작아져 내부 단편화가 줄어듭니다.
- ① 페이지가 작아지면 표도 작아진다고 봤습니다. 같은 프로그램을 더 많은 페이지로 나누므로, 페이지마다 한 행인 페이지 표는 길어집니다.
- ③ 작게 나누면 디스크 일도 준다고 봤습니다. 한 번에 읽는 양이 작아져, 같은 내용을 올리는 데 읽는 횟수는 늘어납니다.
- ④ 조각이 많아지면 그 사이가 빈다고 봤습니다. 페이지는 크기가 같아 빈 프레임 어디에나 들어가므로 외부 단편화가 생기지 않습니다. 외부 단편화는 크기가 다른 세그먼트 쪽 이야기입니다.
2. 다음 (가)~(라)에 맞는 이름을 한글 이름과 영문으로 함께 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
- (가) 주기억장치가 8GB인 컴퓨터에서 12GB 프로그램이 돌아갑니다. 지금 쓰는 부분만 주기억장치에 두고 나머지는 디스크에 둡니다.
- (나) 프로그램을 4KB씩 똑같이 잘라, 잘린 조각을 주기억장치의 빈자리 아무 데나 넣습니다.
- (다) 프로그램을 코드와 데이터처럼 쓰임에 따라 나누어, 조각마다 크기가 다릅니다.
- (라) 주소를 바꾸려고 표를 보니 그 조각이 든 자리가 적혀 있지 않아, 운영체제가 디스크에서 그 조각을 읽어 옵니다.
정답
받는 답: (가) 가상 메모리(Virtual Memory) · (나) 페이징(Paging) · (다) 세그먼테이션(Segmentation) · (라) 페이지 부재(Page Fault)
(가)의 실마리는 '주기억장치보다 큰 프로그램을 일부만 올려 돌린다', (나)는 '똑같은 크기로 자른다', (다)는 '쓰임에 따라 크기가 다르게 나눈다', (라)는 '표에 자리가 없어 디스크에서 읽어 온다'입니다.
- 틀리는 꼴 세그먼테이션 — (나)에: 뜻 단위로 크기가 다르게 나누는 기법입니다. (나)는 4KB씩 똑같이 잘랐습니다.
- 틀리는 꼴 페이징 — (다)에: 같은 크기로 자르는 기법입니다. (다)는 조각마다 크기가 다릅니다.
3. 그림과 같은 페이지 표(페이지 0·1·2·3 → 프레임 3·7·5·없음, 페이지 1KB)에서 논리 주소 1200의 물리 주소를 구하세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
정답
받는 답: 7344
1200 ÷ 1024 = 1 … 176이라 페이지 1, 오프셋 176입니다. 페이지 1은 프레임 7에 있으므로 7 × 1024 + 176 = 7344입니다.
- 틀리는 꼴 7168: 프레임 7의 시작 주소에서 멈췄습니다. 오프셋 176을 더해야 합니다.
- 틀리는 꼴 1200: 논리 주소를 그대로 썼습니다. 페이지 번호 1을 프레임 번호 7로 바꿔야 합니다.
4. 세그먼트 표가 다음과 같습니다. 논리 주소 (2, 230)을 바꾼 결과를 고르세요.
| 세그먼트 | 시작 주소 | 길이 |
|---|---|---|
| 0 | 2000 | 500 |
| 1 | 6000 | 900 |
| 2 | 3500 | 200 |
- ① 430
- ② 3730
- ③ 6230
- ④ 주소 오류
정답
④입니다. 세그먼트 2의 길이는 200인데 오프셋이 230이라 길이를 넘습니다. 시작 주소에 더하기 전에 길이부터 견줍니다.
- ① 길이 200을 시작 주소로 보고 더했습니다. 더하는 것은 시작 주소 3500입니다.
- ② 3500 + 230을 계산했지만 길이 검사를 빠뜨렸습니다. 오프셋이 길이를 넘으면 더하지 않고 막습니다.
- ③ 위에서 둘째 행을 세그먼트 2로 읽었습니다. 세그먼트 번호는 0부터 셉니다.
더 보기: 프레임이 모두 차 있을 때 무엇을 내보낼지는 페이지 교체 알고리즘에서 봅니다.