좋은 관계형 데이터베이스를 설계하는 목적 중 하나가 정보의 이상현상(Anomaly)이 생기지 않도록 고려해 설계하는 것입니다.
이상현상은 아래와 같은 3가지로 구성됩니다.
갱신 이상
반복된 데이터 중에 일부를 갱신할 시 데이터 불일치 발생
삽입 이상
불필요한 정보를 함께 저장하지 않고서는 정보 저장 불가능
삭제 이상
필요한 정보를 함께 삭제하지 않고서는 정보 삭제 불가능
갱신이상
갱신 이상의 경우 어떤 값을 업데이트 했을 때, 다른 속성값들과의 불일치가 발생하는 현상입니다. 예를들어, 테이블에 사용자의 이름이 같은 사용자 김영진이 2명이상 있다고 가정해봅시다. 여러 명의 사용자 중 한명의 김영진이 김진영이라는 이름으로 개명하여 김영진 -> 김진영으로 바꾸었습니다. 이때, 테이블에는 여러명의 김영진이 있기 때문에 다른 김영진도 바뀔 수 있습니다. 이러한 현상을 갱신 이상이라고 합니다.
삽입 이상
내가 원하는 값만 테이블에 삽입하고 싶은데, 테이블에 필요하지 않을 필드들 때문에 원치 않는 필드의 값도 삽입해야 하는 경우 입니다. 예를들어, id, name, password, school의 정보를 입력해야하는 테이블이 있습니다. 해당 테이블에 저는 학교를 다니지 않아서 Id, name, password만 입력하고 싶지만 school의 정보를 입력하지 않는 이상 데이터를 삽입할 수 없습니다. 이렇게 필드 값을 무엇으로 해야할지 결정 못하는 것이 삽입 이상입니다.
삭제 이상
내가 원하는 값만 테이블에서 삭제하고 싶은데, 하나의 튜플이 삭제를 원하지 않는 속성값도 갖고있기 때문에 같이 지워져서 발생하는 문제입니다. 예를들어, Id, name, password, school의 정보가 담겨져있는 테이블이 있습니다. 여기서 저는 학교를 졸업했기때문에 school의 정보만 삭제하고 싶지만, 테이블이 더 많은 수의 필드로 구성되어 있기 때문에 이것을 지우기 위해서는 지우고 싶지 않은 필드들의 정보도 같이 지워야합니다. 이것이 삭제 이상입니다.
보낼 message body를 gzip 등을 이용해 압축해서 전송하는 것 참고) HTTP HEAD 부분에 Contetn-Encoding을 적어주어야함.
분할 전송
보낼 데이터를 byte 단위로 끊어서 전송하는 것 참고) HTTP HEAD에 Transfer-Encoding = chunked를 추가해줘야함. 참고) Content-Length를 넣으면 안된다. (총 몇 바이트인지 예상이 안되기때문) 아래의 Body로 예시를 들면 5byte Hello 먼저 전송 5byte World 전송 0Byte 전송 용량이 되게 큰 경우에 이렇게 나누어서 전송함
범위 전송
이미지를 받는데, 절반정도 받고 나머지 절반을 받는 형식 이유 : 큰 용량의 데이터를 받는 경우 중간에 받지못하면 많은 양의 데이터를 다시 처음부터 받아야하기 때문
일반 정보
From : 유저 에이전트의 이메일 정보
Referer : 이전 웹 페이지 주소
User-Agent : 유저 에이전트 애플리케이션 정보
Server : 요청을 처리하는 오리진 서버의 소프트웨어 정보
Data : 메시지가 생성된 날짜
From
유저 에이전트의 이메일 정보
일반적으로 잘 사용되지 않음
검색 엔진 같은 곳에서, 주로 사용
요청에서 사용
Feferer
이전 웹 페이지 주소
현재 요청된 페이지의 이전 웹 페이지 주소
A -> B로 이동하는 경우 B를 요청할 때 Referer: A를 포함해서 요청
Referer를 사용해서 유입 경로 분석 가능 (내 사이트를 어디 사이트를 통해 들어왔는지 데이터 분석할 때 많이 사용)
요청에서 사용
참고 : referer는 단어 referrer의 오타 => ...??ㅋㅋㅋ그렇다고합니다...
실제 구글에서 hello를 검색한 뒤, 나무위키를 들어가서 개발자 도구에서 Request Headers를 보시면 referer에 이전 페이지의 주소가 적혀있는 것을 볼 수 있습니다.
User-Agent
유저 에이전트 애플리케이션 정보
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/ 537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36
클라이언트의 애플리케이션 정보 (웹 브라우저 정보, 등등)
통계 정보
어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능 (Chrome, Edge 등등..)
요청에서 사용
Server
요청을 처리하는 ORIGIN 서버의 소프트웨어 정보 (프록시, 캐시 서버를 제외한 진짜 나의 요청을 응답하는 서버 - ORIGIN 서버)
Server : Apache/2.2.22 (Debian)
server : nginx
응답에서 사용
Date
메시지가 발생한 날짜와 시간
Date : Tue, 15 Nov 1994 08:12:31 GMT
응답에서 사용
특별한 정보
HOST : 요청한 호스트 정보 (도메인)
Location : 페이지 리다이렉션
Allow : 허용 가능한 HTTP 메서드
Retry-After : 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
HOST
요청한 호스트 정보 (도메인)
요청에서 사용
필수
하나의 서버가 여러 도메인을 처리해야 할 때 (구글, 네이버 등등과 같은 경우)
하나의 IP 주소에 여러 도메인이 적용되어 있을 때
하나의 서버가 여러 도메인을 처리한다는 것은 가상호스트를 통해 여러 도메인을 한번에 처리할 수 있는 서버로 실제 애플리케이션이 여러개 구동될 수 있다고 합니다.
문제는 호스트가 없이 /hello만 온다면 아래와 같이 어떤 도메인에 /hello인지 모른다는 것 입니다.
그렇기 때문에 HOST를 적어주어야지 서버에서는 정확한 응답을 해줄 수 있습니다.
Location
페이지 리다이렉션
웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동(리다이렉트)
응답코드 3xx에서 설명
201 (Created) : Location 값은 요청에 의해 생성된 리소스 URI
3xx (Redirection) : Location 값은 요청을 자동으로 리다이렉션하기 위한 대상 리소스를 가리킴
Allow
허용 가능한 HTTP 메서드
허용하지 않는 HTTP 메서드로 접근하는 경우
405 (Method Not Allowd)에서 응답에 포함해야함
Allow : GET, HEAD, PUT
Retry-After
유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
503 (Service Unavailable) : 서비스가 언제까지 불능인지 알려줄 수 있음
Retry-After : Fri, 31 Dec 1999 23:59:59 GMT (날짜 표기)
Retry-After : 120 (초단위 표기)
인증
Authorization : 클라이언트 인증 정보를 서버에 전달
WWW-Authenticate : 리소스 접근시 필요한 인증 방법 정의
Authorization
클라이언트 인증 정보를 서버에 전달
Authorization : Basic xxxxxxxxxxxxxxxxxxx
Oauth 인증 등등 value에 들어가는 입력이 다름
WWW-Authenticate
리소스 접근시 필요한 인증 방법 정의
리소스 접근시 필요한 인증 방법 정의
401 Unauthorized 응답과 함께 사용
WWW-Authenticate : Newauth realm= apps",type=1, title="Login to \"apps\"", Basic realm="simple"
인증을 하려면 "New~simple"과 정보를 참고해서 제대로된 인증 정보를 만들라고 응답
쿠키
Set-Cookie : 서버에서 클라이언트로 쿠키 전달 (응답)
Cookie : 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청시 서버로 전달
쿠키 미사용
처음 welcome 페이지 접근
로그인
로그인 이후 welcome 페이지 접근
HTTP는 메시지를 다 보내고나면 연결을 끊기 때문에 쿠키를 사용하지 않으면 서버에서 이전에 로그인을 했던 사용자인지 처음온 사람인지 알 수 있는 방법이 없습니다. (HTTP가 Stateless이기 때문)
4xx (Client Error) : 클라이언트 오류, 잘못된 문법등으로 서버가 요청을 수행할 수 없음
5xx (Server Error) : 서버 오류, 서버가 정상 요청을 처리하지 못함
2xx (성공)
클라이언트의 요청을 성공적으로 처리
200 OK
요청 성공
201 Created
요청이 성공해서 새로운 시소스가 생성
응답 헤더에 "Location : (새로생성된 리소스 URI)"를 포함해서 응답
202 Accepted
요청이 접수되었으나 처리가 완료되지 않는 경우
배치 처리 같은 곳에서 사용
예) 요청 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리함
204 No Content
서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없음
예) 웹 문서 편집기에서 save 버튼 (클라이언트 입장에서 서버에서 데이터를 보내줄 필요가 없음)
결과 내용이 없는 204 메시지만으로 성공을 인식해도 되는 경우
3xx (리다이렉션1)
요청을 완료하기 위해 클라이언트 웹 브라우저의 추가 조치 필요
300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
307 Temporary Redirect
308 Permanent Redirect
리다이렉션 이해
웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동(리다이렉트)
기존 event 시에 /event로 접근하였는데 새로운 이벤트는 /new-event로 접근하는 경우 301 코드와 새로바뀐 path를 Location에 포함해서 응답을 보냅니다. 그렇게되면 웹 브라우저가 스스로 해당 url로 바꾼뒤 새롭게 검색합니다. (자동 리다이렉트)
리다이렉션 종류
영구 리다이렉션 - 특정 리소스의 URI가 영구적으로 이동
예) /members -> /users
예) /event -> /new-event
일시 리다이렉션 - 일시적인 변경
주문 완료 후 주문 내역 화면으로 이동
PRG 패턴 : Post/Redirect/Get
특수 리다이렉션
결과 대신 캐시를 사용
캐시가 만료된 것 같아 캐시와 관련된 정보를 서버에 제공했는데, 서버에서 캐시사용해도 되니깐 계속 사용하라고 응답하는 경우
영구 리다이렉션 - 301, 308
리소스의 URI가 영구적으로 이동
원래의 URL을 사용하지 않고, 검색 엔진 등에서도 변경 인지
301 Moved Permanently
리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
POST로 요청을 했을 시에는 다시 처음부터 입력을 해야됩니다. (POST 요청 메서드가 GET 메서드로 바뀌었기 때문)
308 Permanent Redirect
301과 기능은 같음
리다이렉트시 요청 메서드와 본문 유지(처음 POST를 보내면 리다이렉트도 POST 유지)
일시적인 리다이렉션 - 302, 307, 303
리소스의 URI가 일시적으로 변경
따라서 검색 엔진 등에서 URL을 변경하면 안됨
302 Found
리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
307 Temporary Redirect
302와 기능은 같음
리다이렉트시 요청 메서드와 본문 유지(요청 메서드를 변경하면 안된다.)
303 See Other
302와 기능은 같음
리다이렉트시 요청 메서드가 GET으로 변경
PRG : Post / Redirect / Get
일시적인 리다이렉션 - 예시
POST로 주문후에 웹 브라우저를 새로고침하면?
새로고침은 다시 요청
중복 주문이 될 수 있다.
원칙적으로는 서버에서 막아줘야합니다. 그래도 클라이언트에서도 하나정도는 막아주면 좋습니다. 위의 문제를 해결하기 위해 PRG라는 패턴을 주로 씁니다.
POST로 주문후에 새로 고침으로 인한 중복 주문 방지
POST로 주문후에 주문 결과 화면을 GET 메서드로 리다이렉트
새로고침해도 결과 화면을 GET으로 조회
중복 주문 대신에 결과 화면만 GET으로 다시 요청
3번의 응답 상태 코드는 302, 303 모두 가능합니다.
이렇게되면 사용성이 좋습니다. 사용자의 입장에서 실수로 새로고침해도 결과화면이 깔끔하게 보이고 서버입장에서는 오류가 줄어들기 때문입니다.
위의 경우 303, 307을 권장하지만 현실적으로 이미 많은 애플리케이션 라이브러리들이 302를 기본값으로 사용하고 있다고 합니다. 위처럼 자동 리다이렉션시에 GET으로 변해도 되면 302를 사용해도 큰 문제는 없습니다.
이미지 경로만 URI에 넣어서 GET 요청을하면 서버에서는 해당 경로에 있는 데이터를 클라이언트에게 반환해줍니다. 정적 데이터를 조회할 때는 파라미터가 필요하지 않습니다.
정적 데이터 조회 - 정리
이미지, 정적 테스트 문서
조회는 GET 사용
정적 데이터는 일반적으로 쿼리 파라미터 없이 리소스 경로로 단순하게 조회 가능
동적 데이터 조회 - 쿼리 파라미터 사용
동적 데이터를 조회할 때는 데이터를 서버측에 넘겨줘야합니다. 이때, 쿼리 파라미터를 URI에 추가하여 사용합니다.
동적 데이터 조회 - 정리
주로 검색, 게시판 목록에서 정렬 필터 (검색어)
조회 조건을 줄여주는 필터, 조회 결과를 정렬하는 정렬 조건에 주로 사용
조회는 GET 사용
GET은 쿼리 파라미터를 사용해서 데이터를 전달
HTML Form 데이터 전송 - POST 전송 (저장)
form tag를 사용해 웹브라우저가 submit 버튼을 클라이언트에서 누르게 되면 form의 데이터를 읽어서 http 메시지를 생성해줍니다.
username=kim&age=20
쿼리 파라미터와 거의 유사하게 key=value 스타일로 데이터를 만들고 http body에 넣어준 모습입니다.
만약, 위의 method를 "GET"으로 바꾸면 어떻게 될까요??
GET이니까 body에 데이터가 들어가지 않고 쿼리 파라미터처럼 넣어서 서버로 전달합니다.
HTML Form 데이터 전송 - multipart/form-data
multipart/form-data는 파일 같은 것을 전송할 때 쓰는 인코딩 타입입니다. 이럴 때는 message body에 넣는 방식을 사용해야합니다. message Body에 boundary를 통해 각각의 key의 value가 어떤 값인지 나타낼 수 있또록 자동으로 생성해줍니다.
HTML Form 데이터 전송
HTML Form submit시 POST 전송
예) 회원 가입, 상품 주문, 데이터 변경
Content-Type : application/x-www-form-urlencoded 사용
form의 내용을 메시지 바디를 통해서 전송(key=value, 쿼리 파라미터 형식)
전송 데이터를 url encoding 처리
예) abc김 -> abc%EAA%B9%80
HTML Form은 GET 전송도 가능
Content-Type: multipart/form-data
파일 업로드 같은 바이너리 데이터 전송시 사용
다른 종류의 여러 파일과 폼의 내용 함께 전송 가능 (그래서 이름이 multipart)
참고: HTML Form 전송은 GET, POST만 지원
HTTP API 데이터 전송
보통 라이브러리가 있는데 사용해서 넘기면 됩니다.
HTTP API 데이터 전송 - 정리
서버 to 서버
백엔드 시스템 통신
앱 클라이언트
안드로이드, 아이폰
웹 클라이언트
HTML에서 Form 전송 대신 자바 스크립트를 통한 통신에 사용 (AJAX)
예) React, VueJs 같은 웹 클라이언트와 API 통신
POST, PUT, PATCH : 메시지 바디를 통해 데이터 전송
GET: 조회, 쿼리 파라미터로 데이터 전달
Content-Type: application/json을 주로 사용 (사실상 표준)
TEXT, XML, JSON 등등
HTTP API 설계 예시
HTTP API - 컬렉션
POST 기반 등록
예) 회원 관리 API 제공
HTTP API - 스토어
PUT 기반 등록
예) 정적 컨텐츠 관리, 원격 파일 관리
HTML FORM 사용
웹 페이지 회원 관리
GET, POST만 지원
회원 관리 시스템 API 설계 - POST 기반 등록
회원 목록 /members -> GET
회원 등록 /members -> POST
회원 조회 /members/{id} -> GET
회원 수정 /members/{id} -> PATCH, PUT, POST
회원 삭제 /members/{id} -> DELETE
회원 관리 시스템 POST - 신규 자원 등록 특징 (서버에서 리소스 URI를 결정하고 만들어줌)
클라이언트는 등록될 리소스의 URI를 모릅니다.
회원 등록 /members -> POST
POST /members
서버가 새로 등록된 리소스 URI를 생성해줍니다.
HTTP/1.1 201 Created Location: /members/100
컬렉션(Collection)
서버가 관리하는 리소스 디렉토리
서버가 리소스의 URI를 생성하고 관리
여기서 컬렉션은 /members
파일 관리 시스템 API 설계 - PUT 기반 등록
파일 목록 /files -> GET
파일 조회/files/{filename} -> GET
파일 등록/files/{filename} -> PUT
파일 삭제/files/{filename} -> DELETE
파일 대량 등록 /files -> POST
파일 관리 시스템 PUT - 신규 자원 등록 특징
클라이언트가 리소스 URI를 알고 있어야 합니다.
파일 등록 /files/{filename} -> PUT
여기서 filename을 클라이언트가 알고 있어야합니다.
클라이언트가 직접 리소스의 URI를 지정합니다.
스토어(Store)
클라이언트가 관리하는 리소스 저장소
클라이언트가 리소스의 URI를 알고 관리
여기서 스토어는 /files
POST 등록과 PUT 등록 중 많이 사용하는 것은 POST기반의 컬렉션을 많이 사용합니다.
HTML FORM 사용
HTML FROM은 GET, POST만 지원
AJAX 같은 기술을 사용해서 해결 가능 -> 회원 API 참고
여기서는 순수 HTML, HTML FORM 이야기
GET, POST만 지원하므로 제약이 있음
회원 관리 시스템 API 설계 - HTML FORM 기반
회원 목록 /members -> GET
회원 등록 폼 /members/new -> GET
회원 등록 /members/new, /members -> POST
회원 조회 /members/{id} -> GET
회원 수정 폼 /members/{id}/edit -> GET
회원 수정 /members/{id}/edit, /members/{id} -> POST
회원 삭제 /members/{id}/delete -> POST
회원 등록(new), 수정(edit), 삭제(delete)의 경우 GET, POST만 사용할 수 있는 HTML FORM에서는컨트롤 URI(동사로된 URI)를 쓸 수 밖에 없습니다.
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
// 생성자는 외부에서 호출못하게 private 으로 지정해야 한다.
}
// 1. Eager Initailization
public static Singleton getInstance() {
return instance;
}
// 2. Lazy Initailization
public static synchronzied Singleton getInstance() {
if(uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// 3. Lazy Initialization. DCL
public static Singleton getInstance() {
if(uniqueInstance == null) {
synchronized(Singleton.class) {
if(uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
싱글톤 패턴의 특징은 두가지가 있습니다.
private 생성자
static method
private 생성자는 외부에서 객체를 생성할 수 없도록하기위해 사용합니다. (객체를 오직 한번만 생성하도록) static 키워드의 특징을 이용해서 클래스 로더가 초기화 하는 시점에서 정적 바인딩(static binding)을 통해 해당 인스턴스를 메모리에 등록해서 사용하는 것 입니다.
싱글톤 패턴을 사용하는 이유
메모리 측면
최초 한번의 new 연산자를 통해서 고정된 메모리 영역을 사용하기 때문에 해당 객체에 접근할 때 사용되는 메모리 낭비를 방지할 수 있습니다.
쉬운 데이터 공유
싱글톤 인스턴스는 전역으로 사용되는 인스턴스이기 때문에 다른 클래스의 인스턴스들이 접근하여 사용할 수 있습니다.
하지만, 여러 클래스의 인스턴스에서 싱글톤 인스턴스의 데이터에 동시에 접근하게 되면 동시성 문제가 발생할 수 있으니 유의하여 설계해야 합니다.
싱글톤 패턴의 문제점
싱글톤 패턴을 구현하는 코드 자체가 많이 필요합니다.
앞서 소개한 구현 방법외에도 정적 팩토리 메서드에서 객체 생성을 확인하고 생성자를 호출하는 경우에 멀티스레딩 환경에서 발생할 수 있는 동시성 문제 해결을 위해 syncronized 키워드를 사용해야 합니다
테스트하기 어렵다.
싱글톤 인스턴스는 자원을 공유하고 있기 때문에 테스트가 결정적으로 격리된 환경에서 수행되려면 매번 인스턴스의 상태를 초기화시켜주어야 합니다. 그렇지 않으면 애플리케이션 전역에서 상태를 공유하기 때문에 테스트가 온전하게 수행되지 못합니다.
의존 관계상 클라이언트가 구체 클래스에 의존합니다.
new 키워드를 직접 사용하여 클래스 안에서 객체를 생성하고 있으므로, 이는 SOLID 원칙 중 DIP (의존관계역전)를 위반하게 되고 OCP (개방-폐쇄)원칙 또한 위반할 가능성이 높다. => 스프링에서는 빈 컨테이너를 통해 해결합니다.
보조 기억장치에 비해 상대적으로 작은 크기를 가지고 있는 메인 메모리를, 더욱 더 효율적이고 대용량의 프로그램을 사용하기 위해 사용하는 기술입니다. 특정 시점마다 실제 사용하는 메모리는 그렇게 크지 않다는 점에 착안해서 고안된 기술입니다.
가상 메모리를 사용하게 되면 프로세스 간 공간 분리를 하게 되는데 이를 통해 프로세스 간 메모리 영역 침범 이슈를 방지할 수 있고, 보조 기억장치를 활용하면서 메모리 용량 부족에 대한 이슈도 해결할 수 있습니다.
가상 메모리 기법을 사용하게 되면 CPU는 메모리의 실제 주소인 Physical Address 대신 Virtual address에 먼저 접근하게 됩니다. 이때 페이지 테이블을 참조하여 Virtual Address를 Physical Address로 변환하여 실제 메모리에 접근하게 되는데 이러한 변환 과정이 굉장히 빈번하게 일어나고 속도가 굉장히 중요하므로 MMU라는 하드웨어 칩의 지원을 받습니다.
MMU란?
MMU는 Memory Management Unit으로 CPU가 코드를 실행하며 가상 메모리 주소에 접근할 때 가상 메모리 주소를 실제 물리적인 주소로 변환해주는 하드웨어 장치입니다.
Page란?
가상 메모리 기법을 사용할 때 어느정도의 크기씩 실제 메모리에 올려놓는 기본 단위가 되는 것이 페이지입니다.
페이지 단위로 관리하게 되며 페이지 번호를 바탕으로 가상 메모리 주소와 실제 메모리 주소를 매핑하여 페이지 테이블에 기록하고 관리하게 됩니다.
가상 메모리 주소 = (p, d)로 이루어져있고, p는 가상 메모리 페이지, d는 distance로 p 내 offset을 의미합니다.
가상 메모리 기법의 흐름
지금까지 배운 가상 메모리 기법의 흐름을 정리해보면, CPU가 명령어를 실행하던 중 가상 메모리 주소를 참조하게 되면 하드웨어 칩셋인 MMU를 거쳐서 실제 메모리에 올라가있는 페이지 테이블을 참조하여 실질적인 메모리 주소로 변환하게 되고 메모리에 접근하게 됩니다. 메모리에 반복적으로 접근하고 데이터를 읽어오게 되는데 이러한 속도는 CPU나 레지스터 처리 속도에 비하면 굉장히 느린 속도입니다. 이 부분에서 성능 향상을 위해서 TLB라는 하드웨어를 사용하게 됩니다.
TLB(Translation Lookaside Buffer)란?
TLB란 최근에 접근한 페이지 정보를 기록하는 하드웨어 칩셋입니다. 즉, 가상 메모리 주소가 한번 물리 주소로 변환되면 TLB에 기록하고 그 다음부턴 MMU가 페이지 테이블을 참조하는 것이 아닌 TLB를 통해 물리 주소를 먼저 찾습니다. 이를 통하여 상대적으로 속도가 느린 메모리에 접근하는 횟수를 줄여 성능을 향상 시켜줍니다.
페이지 폴트(Page fault)란?
가상 메모리 주소를 통해서 실제 물리 주소를 얻고 메모리에 접근했지만 내가 원하는 페이지가 실제 메모리에 적재되어 있지 않을수도 있습니다. 이렇게 내가 찾는 페이지가 실제 메모리에 현재 적재되어 있지 않을 때를 페이지 폴트라고 합니다. 페이지 폴트가 발생하면 보조기억장치에서 지금 내가 필요한 페이지를 가져오게 됩니다. 보조 기억장치는 메모리보다 속도가 더 느리기 때문에 자주 참조하면 성능이 떨어지게 됩니다. 따라서 페이지 폴트를 줄이기 위해서 다양한 기법들이 사용됩니다.
페이지 교체 알고리즘
페이지 폴트가 발생했을 시 물리 메모리에 비어있는 프레임이 있다면, 비어있는 프레임에 원하는 메모리를 보조 기억장치에서 가져오면 됩니다. 하지만, 프레임이 가득 차 있을 시에는 페이지 교체 알고리즘을 통해 빈 프레임을 만들어주고 보조 기억장치에서 원하는 메모리를 가져와 적재해야 합니다. 페이지 교체 알고리즘에는 FIFO, LRU 등이 있습니다.
FIFO는 가장 먼저 물리 메모리에 적재된 페이지를 선택하는 방식입니다. LRU는 Least Recent Used의 약자로 가장 오랫동안 사용되지 않았던 페이지를 선택하는 방식입니다.