메모리 단편화
- 사용 가능한 메모리가 충분히 존재하지만 할당이 불가능한 상태
고정 분할 기법
내부 단편화(internal fragmentation)
:
: 분할된 영역이 할당된 프로세스 크기 보다 클 때 남는 공간 -> 프로세스가 필요한 양 보다 크게 할당되었을 때
외부 단편화(external fragmentation)
: 분할된 공간의 크기가 작아 프로세스를 할당할 수 없어서 남는 빈공간 -> 메모리 할당/반환 과정이 반복되면 중간 중간 사용하지 않은 메모리들이 발생
가상 메모리(Virtual Memory)
: 물리 메모리(실제 메모리)의 크기와 상관없이 메모리를 이용할 수 있도록 지원하는 기술
-> 크기가 다른 물리 메모리에서 일관되게 프로세스를 실행할 수 있게 하는 기술
-> 페이징, 세그멘테이션
페이징(paging)?
- 외부 단편화가 발생했던 근본적인 문제?
=> 각기 다른 크기의 프로세스가 메모리에 연속적으로 할당되었기 때문
연속 할당의 문제점 => 외부 단편화(external fragmentation)
=> 프로세스를 일정 크기로 자르고 이를 메모리에 불연속적으로 할당할 수 있다면 ?
페이징
- 프로세스의 논리 주소 공간을 page라는 일정 단위로 자르고,
- 메모리의 물리 주소 공간을 frame이라는 페이지와 동일한 일정한 단위로 자른 뒤
- 페이지를 프레임에 할당하는 가상 메모리 관리 기법
- page: 가상 메모리를 일정한 크기로 나눈 블록
- frame: 물리 메모리를 일정한 크기로 나눈 블록
페이징에서의 Swaping
- 프로세스 단위의 swap in, swap out이 아닌 페이지 단위의 swap in, swap out
- 메모리에 적재될 필요가 없는 페이지들은 보조기억장치로 스왑 아웃
실행에 필요한 페이지들은 메모리로 swap in
- 프로세스를 이루는 페이지가 어느 프레임에 적재되어 있는지 cpu가 일일이 알기는 어렵다.
- 프로세스가 메모리에 불연속적으로 배치되어 있다면 cpu는 이를 순차적으로 실행할 수 없음
- 다음에 실행할 명령어 위치를 찾기가 어려워짐
=>
페이지 테이블
- 실제 매모리 내의 주소, 물리 주소에 불연속적으로 배치되더라도
cpu가 바라보는 주소인 논리 주소에는 연속적으로 배치되도록 하는 방법
페이지 번호와 프레임 번호를 짝지어 주는 일종의 이정표
- 페이지는 모두 같은 크기
물리 주소 공간을 페이지와 같은 사이즈로 나눈 것 = 프레임(frame)
- 페이지 사이즈(frame size)는 하드웨어에 의해 정해진다.
- 페이지의 크기는 일반적으로 2의 제곱수 사용
: 4kb(2^12) ~ 1GB(2^2)
- 페이지 테이블을 이용해 논리주소에서 프레임을 가리키는 물리 주소로 매핑
-> 외부 단편화는 발생하지 않지만 내부 단편화는 발생한다.
페이지 테이블의 특징
-
모든 프로세스가 페이지 테이블을 갖는다.
-
페이지 테이블은 메인 메모리에 저장된다.
-
Page Table Base Register(PTBR)
페이지 테이블을 가리키고 있다.
-
Page Table Length Register(PTLR)
페이지 테이블의 사이즈를 가리키고 있다.
-
PCB에 이런 레지스터의 내용 저장 => context switching이 일어날 때 교체된다.
-
모든 data/instruction 접근 은 2번의 메모리 접근이 필요 -> 페이지 테이블에 접근하는 오버헤드가 존재
Process Control Block(PCB)
PCB: 각 Process와 관련된 정보들
대부분 운영체제는 하드웨어/메모리에 직접 접근해야 하는 경우가 많아서 Pointer 사용 -> c로 구성
- process state: new, running, waiting, ready, terminated
- program counter
- cpu register: 범용 레지스터 - 프로세스가 CPU에서 실행될 때 상태를 저장하는 레지스터들의 값
- cpu scheduling: priority, scheduling queue에 대한 포인터
- memory management: cpu, real-time used, time limits, process number
- I/O status: 할당된 I/O 장치들의 list, 열려있는 파일들의 list
문맥 교환이 필요한 이유?
- cpu는 한 번에 하나의 프로세스만 실행 가능
-> 동시에 여러 프로세스 수행하는 것처럼 보이게 하기 위해 여러개의 프로세스를 번갈아가며 수행한다.
시스템 콜
프로세스가 시스템의 자원이나 서비스를 필요로 하 경우 운영체제에게 요청하는 것
- 사용자 프로세스가 시스템 콜을 요청하면 커널 모드로 변경 (User mode -> Kernel mode)
- 커널은 내부적으로 각각의 시스템 콜을 구분하기 위해 기능별로 고유 번호를 할당하고, 번호에 해당하는 제어 루틴을 커널 내부에 정의
- 커널은 요청받은 시스템 콜에 대응하는 기능 번호를 확인한다.
- 커널은 그 번호에 맞는 서비스 루틴을 호출한다.
- 서비스 루틴을 모두 처리하고 나면 커널 모드 -> 사용자 모드로 전환
demand-zero memory
demand => 필요할 때 0으로 초기화해주는 메모리
페이지가 실제 사용되기 전까지는 물리적 메모리에 할당 X.
실제로 해당 페이지가 접근되어 사용될 때 0으로 채워진 페이지를 할당하고 초기화
- lazy한 상태=> 필요해질 때까지 실제 자원을 할당하거나 동작을 실행하지 않는 것
- 힙 영역이 초기화 되지 않은 상태로 시작 -> 프로그램이 메모리를 필요로 할 때 실제로 사용되기 전까지 초기화되지 않은 상태 유지
=> 메모리의 효율적인 사용이 가능해짐. 프로세스가 필요할 때 메모리를 할당 -> 더 많은 프로세스 관리하기가 수월. 실제 사용하지 않는 메모리에 대한 낭비 줄일 수 있음
참고)
https://code-lab1.tistory.com/55
https://velog.io/@orcasuit/demand-zero-memory