가상 메모리와 프로세스

nGyu·2022년 4월 5일
0

OS

목록 보기
8/10

여태 스케줄링과 메모리 관리전략 등 다양한 부분에서 공부를 하며 VMM이라는 개념에 대해서 여러번 보았을것이다.
여기서, VMM이란 무엇인가? Virtual Memory Management 의 약어인데, 이 풀네임을 보았을 때 Virtual Memory라는 단어가 나온다. 즉, 가상 메모리 이다.

가상 메모리에 대해서 여러번 언급을 하며 간단하게만 설명을 했지 실제로 이 가상메모리가 어떤것이 고 어떤 구조인지 알지는 못했다.

이번에는 이 가상메모리에 대해서 자세히 알아보도록 하겠다.


가상메모리

가상 메모리를 이해하기 위해서는 약간의 배경지식이 필요하다.

  1. 컴퓨터 구조
  2. 프로그램이 실행되는 것
  3. 주소 바인딩
  4. 스왑영역

이렇게 총 4가지의 배경지식이 필요하다.

컴퓨터 구조

컴퓨터에서 일을 즉, 연산을 누가할까? 바로 CPU 이다.
하지만, 연산을 위해서는 메모리의 값을 참조해야한다.

Register라는 개념을 들어본 적 있는가?
CPU는 연산을 할 때 Register의 값을 참조하게 된다.

Register란, 자료를 보관하는 매우 빠른 기억장소이다. 하지만 용량이 매우 작다.

이런 작은 용량을 어떻게 보안할 수 있을까? 하다가 Register 다음으로 가장 가까운 Pysical Memory를 참조하게 된다.

여기서 Register와 Pysical Memory는 회발성이며, 빠르지만 용량이 매우 작다. 그래서 더 많은 내용을 저장하기에는 문제가 있다.
이러한 문제를 어떻게 해결해야할까?

바로 느리지만 휘발성이지 않고 용량이 큰 DISK(보조 기억장치)를 이용하는것이다.

하지만, CPU는 Pysical Memory까지밖에 참조를 할수 없기 때문에 OS의 힘을 빌려 Disk와 I/O 작업을 진행하게 된다.

프로그램이 실행 되는 것

위에 내용을 되짚어보면 컴퓨터에서는 CPU가 일을 한다.
일을 하기 위해서는 프로그램이 존재해야 하는데 이 프로그램은 어디에 있어야 할까?

CPU는 Register와 Pysical Memory까지만 접근이 가능하다고 하였다. 하지만, Register는 용량이 매우 작아 여러 프로그램을 올리기에는 버겁고, Pysical Memory가 그나마 Register 보다는 용량이 크다.

그렇다면 프로그램의 정보가 최소한 Pysical Memory에 올라와 프로세스 형태로 배치가 되어야 CPU가 일을 할 수 있다는 것이다.

프로그램의 실행파일은 Disk에 존재하게 되는데, 프로그머가 작성한 코드만 존재한다면 이는 컴파일러와 링커의 작업으로 실행파일이 생성 된다.

해당 프로그램을 실행하면 fork() 요청으로 새 프로세스를 생성하고 exec() 요청으로 로더를 호출한다

로더(Loader) : 새로 생성된 프로세스의 주소공간을 사용하여 지정된 실행 파일을 메모리에 올리는데 사용된다.

CPU는 샐행 파일을 실행하게 되면 0번부터 시작하는 프로세스마다 독자적인 주소 공간을 생성하고, 이 주소를 바라보는데 이는 “논리주소" 라고 한다. 즉, 여기까지 정리를 해보면 CPU가 일을 하기 위해서는 논리 주소가 메인 메모리에 올라와 있어야 일을 할 수 있다. 라는것을 알 수 있다.

이제, 논리주소와 물리주소가 등장하게 된다.

  • 논리 주소(= 가상 주소) : 각 프로세스에게 CPU가 할당하는 주소
  • 물리 주소 : 메모리가 취급하는 주소

여기서 보면 무언가 이상하다는것을 느낄 수 있다.

CPU는 논리 주소를 바라보지만, 메모리에는 물리주소를 취급한다.

이 두개의 주소는 같은 값을 가질 수 있지만, 바인딩의 시점에 따라서 다른 값을 가질 수 있다.

여기서 다양한 바인딩 방법이 나오게 된다.

주소 바인딩

물리적 메모리 주소가 결정되는 시기에 따라서 컴파일 타임 바인딩, 로드 타이 바인딩, 실행 시간 바인딩 총 3개의 바인딩 방식이 나뉘게 되는데, 가상메모리를 사용하기 위해서는 실행 시간 바인딩이 지원되어야 한다. 이 바인딩을 하게 되면 논리주소(가상주소)와 물리 주소의 값이 달리지게 된다.

실행시간 바인딩을 하기 위해서는 하드웨어적인 지원이 꼭 필요하다.

CPU가 메모리에 접근을 할 때 주소값을 기반으로 참조를 하게 되는데, 이 때 매번 주소 매핑 테이블을 이용해 바인딩을 점검하게 된다. 이는 기준 레지스터와 한계 레지스터를 포함한 MMU라는 하드웨어의 지원이 필요하다.

MMU

기준 레지스터에는 물리적 메모리의 시작 주소가 저장이 되어있어 “논리적 주소 + 기준 레지스터값“ 으로 물리적 주소의 위치를 찾게 된다.

하지만, 프로세는 각각 고유의 값을 가지고 있기 때문에 CPU가 할당하는 논리 주소가 중복이 될 수 있다. 이러한 문제점을 해결하기 위해서 기준 레지스터는 각 프로세스에 맞게 설정을 하게 된다. 이를 MMU기법이라고 한다.

스왑영역

CPU가 프로그램을 실행하기 위해서는 메모리에 프로세스가 올라와 있어야 한다고 했다.
해당 메모리에는 프로세스가 8GiB중 7.5GiB이 사용중인데, 만약 600MB짜리 프로세스가 등록되려고 한다.
그렇게 되면 실행을 할 수 있을까? 혹은, 메모리가 1GiB인데 2GiB 의 메모리를 사용하는 프로세스가 등록되면 어떻게 될까? 이는 모두 메모리 공간이 부족하여 실행이 힘들것이다.

이 때 메모리 공간의 확장 영역으로스왑 공간을 사용한다.

이는, Disk에 존재를 하지만 Pysical Memory의 확장 영역이다. Pysical Memory의 공간이 부족하면 일시적으로 실행중인 프로세스 중 한 개의 프로세스를 Swap 영역으로 Swap Out시키게 되며 이 후 메모리 부족 문제가 해결 되었을 시 Pysical Memory에서 Swap Out된 프로세스를 다시 Swap In하여 Pysical Memory에 적재를 하게 된다.

여기서 보았을 때 Swap 영역은 Disk에 존재하기 때문에, OS에 의해서 I/O가 일어나게 된다.

다시 가상메모리

가상 메모리가 왜 필요할까?

자, 우선 우리가 여태 공부했던 기본 지식을 정리하며 생각을 해보자.

CPU는 일을 하기 위해서 Pysical Memory에 접근을 하게 되는데, 이 Pysical Memory에 접근을 할 때 Logical Address를 이용해서 접근을 한다. 하지만, Pysical Memory는 Pysical Address만을 이용하기 때문에 CPU에서 MMU하드웨어를 이용하여 Logical Address를 Pysical Address로 매핑을 해 준다. 그렇게 하여 CPU는 메모리에 접근을 해 할당 할 프로세스를 가져오게 되고, 이 프로세스의 작업을 진행한다.

하지만, 메모리에 너무 많은 양의 프로세스가 등록이 되어있고, 새로운 프로세스를 등록하기에는 어려움이 있다. 그렇기 때문에 Disk에 Swap Area라는 Pysical Memory의 확장 영역을 생성하게 되고, 이 Swap Area로 Pysical Memory에서 실행되고 있는 프로세스 자체를 Swap Out하며 새로운 프로세스를 메모리에 등록을 한다. 이 후 메모리 부족 현상이 해결이 되면 Swap In을 하게 되는데, 이 때 CPU는 Pysical Memory까지만 접근이 가능하므로, OS의 힘을 빌려 Disk 에 I/O를 하게 된다.
자, 이게 위 내용들을 간략(?) 하게 정리를 한 것이다.
이를 보았을 때 무언가 이상한 생각이 드는가? 바로, OS의 힘을 빌려 Disk에 I/O를 하게 된다면, 성능에 큰 문제가 생기게 된다.

한 두개의 프로세스를 Swapping 할때는 문제가 없다고 느낄 수 있겠지만, 더 많은양의 프로세스를 Swapping하게 된다면 어떻게 될까? 또 아예 Pysical Memory의 크기를 벗어나는 프로그램을 실행시켜야만 한다면..? 정말 머리가 지끈지근 할 것이다.


좋은 프로그램일수록 자주 사용되지 않는 방어 코드나 관리 코드가 많다고 한다.
사용도 잘 하지 않지만, 이러한 코드를 궂이 계속해서 연속적으로 Pysical Memory에 등록을 해 두어야 할까?
필요하지 않는 코드의 메모리까지 궂이 Pysical Memory에서 메모리를 할당받아 사용하기에는 메모리의 낭비가 심하다.

이 때 자주 사용되지 않는 코드는 따로 뺄 수 없을까? 하며 나온 개념이 바로 가상 메모리 이다.

가상 메모리는 자주 사용되며 꼭 필요한 부분만 Pysical Memory에 올리게 되며, 나머지 자주 사용하지 않는 코드는 가상 주소 공간에 등록을 하게 된다.

가상 주소 공간

가상 주소 공간은, Swap Area와 비슷한 개념으로 Virtual Memory를 저장하며 해당 Virtual Memory의 Address를 저장하는 공간을 의미한다.

여기서 VMM(Virtual Memory Managemet)라는 개념도 함께 등장하게 되는데, Virtual Address Area는 Swap Area와 비슷하다고 언급을 했다.

이게 비슷한 이유는 A가 분리되어 A1은 Pysical Memory, A2는 Virtual Memory에 저장이 된다.
여기서 A1에서 필요한 부분만 A2와 Swapping이 발생하는데, 이러한 과정때문에 Swap Area와 Vitual Memory Area는 비슷하다고 한 것이다.

그렇다면 Swap Area == Virtual Memory Area인가? 정답은 아니다.

  • Swap Area → 프로세스 그 자체의 Swapping이 발생한다.
  • Virtual Memory Area → 프로세스의 일부분만 Swapping이 발생한다.

메모리간 페이지 공유

메모리간 페이지 공유, 사실 처음 보았을 때 이 단어가 무슨 뜻인지 알지 못했다.
하지만, 위의 기초 지식을 알고 가상 메모리의 등장 배경을 알고나니 이 단어의 뜻을 알게 되었다.

바로, Pysical Memory와 Virtual Memory간의 “페이지” 공유이다.

페이지는 메모리 관리 기법에서 OS는 Paging과 Sementation을 함께 사용한다고 하였는데, 이 때 Segmentation이 “페이지"단위로 묶인다고 했다.

그렇다면, 이 단어에서 알 수 있는 사실 한 가지는 한 Page 안의 Segment가 논리적으로 독립된 내용들이 서로 나뉘어져 필요한 부분은 Pysical Memory에 올라가 있고, 많이 필요하지 않은 부분은 Virtual Memory에 올라가 있다는 사실 이다.

페이지들은 서로의 정보를 공유하여 메모리에 프로세스가 실행중인지 알 수 있다.


위에 가상 메모리개념이 나온 배경에 대해 설명을 하며 코드의 필요한 부분만 Pysical Memory에 올리고 나머지는 Virtual Memory에 등록을 한다고 언급했다.

그런데 어떻게 이렇게 분류를 하고 각각의 메모리에 등록을 하는것일까?

Demand Paging(요구 페이징)

Demand Paging 이란, 필요한 프로그램만 메모리에 적재하는 방법을 뜻한다.
이 방법은 스와핑 기법과 유사한데, 프로세스를 샐행하고 싶으면 메모리로 읽어 들이는데 이 때 모든 프로세스를 읽어오지 않고 Lazy Swapper 방식을 사용한다.

Lazy Swapper : 그 페이지가 필요하지 않는 한 메모리에 적재하지 않는다.

Swapper는 전체 프로세스를 관리 하지만, 페이저는 프로세스 내의 개별 페이지들을 관리한다. 요구 페이징과 관련해서는 스와퍼 보다는 페이저가 더욱 가깝다고 할 수 있다.

제대로 설명하자면, 해당 방법은 프로세스의 이미지를 Backing Store에 저장을 한다.
Backing Store는 Swap Device로 하드웨어 부분인데, 페이지를 임시로 보관을 하는 공간이다. 프로세스는 페이지의 조합이기 때문에, 필요한 페이지만 메모리에 올린다. 이것을 요구 페이징 이라고 한다.

자, 그럼 위에서 페이지들은 서로의 정보를 공유하여 프로세스가 실행중인 지 알 수 있다고 했다.
또, 필요한것만
그런데 이를 어떻게 공유하고 알 수 있는것일까?

바로, Valid와 Invalid 라는 유/무효 비트를 통해서 알 수 있다.

  • Valid : 해당 페이지가 메모리에 있음
  • Invalid : 해당 페이지가 메모리에 없음
    • 이는, 해당 페이지가 메모리에 없음을 의미하고, Page Fault가 발생했다고 한다.

Page Fault Trap(페이지 부재 트랩)

Page Fault 발생은 Page Table에서 특정 메모리의 주소값이 Invalid가 되었다는것을 의미한다.
이 때, 해당 프로세스에 대한 CPU의 제어권은 OS에게 넘어가게 되고, OS는 Swap Area에서 해당 페이지를 참조하여 Pysical Memory의 빈 공간에 올리게 된다.

profile
지금보다 내일을, 모레를 준비하자

0개의 댓글