中庸
article thumbnail

이전 Memory Management 포스팅에서 잠깐 Virtual Memory 에 대해 언급한 바 있습니다.

 

이번 포스팅에서 이것에 대해 자세히 알아보겠습니다.

 

Virtual Memory

이전 Memory Management 방식에서 Paging, Segmentation 방식으로 메모리를 관리하는 방법에 대해 배웠습니다. 프로세스가 반드시 한 번에 메인 메모리에 로드되거나 Swap out 될 필요없이, 프로세스를 작게 쪼개 일부분만 올려 운용할 수 있습니다.

 

그렇기 때문에 일부분은 보조 기억장치에서 저장하고 있다가 필요할 때 메인 메모리에 로드하는 방법으로 메모리를 관리하면, 메인 메모리 공간을 더욱 효율적으로 사용할 수 있습니다.

 

이렇게 메인 메모리와 보조 기억장치를 함께 사용하여 프로세스를 관리하는 할 때, 보조 기억장치에서 프로세스를 관리하는 메모리를 Virtual Memory (가상 메모리) 라고 합니다.

 

 

Advantage of Virtual Memory (가상 메모리 사용의 장점)

  • 메인 메모리를 더욱 효율적으로 이용할 수 있음
  • 더 많은 프로세스를 메인 메모리에 올려둘 수 있음. Throughput 증가
  • 이전에는 프로세스의 크기가 반드시 메인 메모리보다 작아야했으나, Virtual Memroy 를 사용함으로써 이러한 제약에서 자유로워짐
  • 따라서, 프로그램 개발 시 이식성이 좋아짐. 하드웨어 제약 조건을 덜 고려해도 되니까! (메인 메모리에 프로세스의 모든 Context 를 올려둘 필요가 없음)

 

 

반드시 프로세스의 모든 부분이 메인 메모리에 로드되어 있을 필요가 없다. 보조 기억장치에 일부 존재해도 OK.

 

 

그렇다면, 프로세스를 Execution 하는 데에 필요한 부분이 보조 기억장치에 있다면 어떤 일이 일어나는지 살펴봅시다.

 

 

요약하자면, 필요한 부분이 메인 메모리에 로드되어 있지 않으면 Page Fault 라는 Interrupt 가 발생하여 실행 중인 프로세스를 Blocked 상태로 만든 뒤 필요한 부분을 메인 메모리에 로드하고 다시 프로그램을 Execution 합니다.

 

 

Virtual Memory 를 통해 얻는 장점도 있지만 다음과 같은 단점도 예상해볼 수 있습니다.

 

"어? 그러면 보조 기억장치에서 프로세스 Context 를 가져오려면 느리니까 전체적으로 성능 저하가 발생하지 않나요?"

 

맞습니다. 프로세스의 모든 Context 를 메인 메모리에 올리는 것보다, 당연히 Virtual Memory 를 사용하여 관리하면 느려집니다.

 

하지만 다음의 Principle of Locality 에 의해서, 아주 큰 성능저하가 발생하지 않음을 예상할 수 있습니다.

 

Principle of Locality : 요약하면, 자주 쓰이는 놈들은 정해져 있고, 불리는 놈들만 불리는 특성이 있다.

 

 

 

Demand Paging

이전 Memory Mangement 포스팅에서 메모리를 관리를 하는 방법으로 Paging 에 대해 알아보았습니다.

 

이번 포스팅에서는 Virtual Memory 를 활용한 Paging 방식인 Demand Paging 에 대해 알아보겠습니다.

 

Demand Paging 이란? : Demand Paging 이란, Virtual Memory 에 존재하는 Process 의 Page 중 Access 할 필요가 있는 Page 를 Main Memory 로 올리되, 이 때 Page Table 을 이용하여 Virtual (Logical) Address 를 Physical Address 로 매핑하는 것을 의미합니다.

 

Virtual Address 를 Physical Address 로 변환할 때, 하드웨어의 도움을 받아 빠르게 변환할 수 있습니다.

 

Demand Paging, Virtual Memory 에 존재하는 페이지를 Page Table 을 통해 Physical Address (Frame) 으로 매핑시킬 수 있다.

 

Page Table Register 라는 하드웨어의 도움을 받아 Logical Addr. 을 Physical Addr. 로 빠르게 변환할 수 있다. 이 떄 Page Table 의 시작 주소는 PCB 에 기록되며, 따라서 Context Swtiching 시 Page Table Base Register 값도 바꿀 수 있다.

 

페이지 테이블을 잘 보면, Frame 주소를 저장하는 공간과 더불어 빈 칸이 보입니다.

 

페이지 테이블 인덱스 한 칸을 Page Table Entry 라고 부르며 이 공간에는 다음과 같은 정보가 저장됩니다.

 

Page Table Entry

 

페이지 하나의 크기가 4096바이트 (2^12) 임을 유의하자. 그렇다면 4GB 공간에서 페이지의 개수는 2^20 (2^32 / 2^12) 개 존재할 수 있다. 따라서 32비트 컴퓨터에서 메인 메모리 상의 프레임의 개수는 2^20개

 

Page Table Entry 또한 4Bytes 공간인데, 이 공간에는 프레임 넘버와 더불어 Page Control Information 이 저장됩니다.

 

현재 페이지가 메인 메모리 상에 올라와있는지 알려주는 P(Present) Bit 과 더불어 다음과 같은 정보들이 저장됩니다.

 

M bit 은 Modified 여부를 체크하는 비트, R bit 은 프로세스가 이 페이지에 접근한 적 있는지에 대한 비트. 즉 M bit 이 더 엄격한 조건이다.

 

 

M bit 의 존재 이유에 대해 조금 더 자세히 살펴보겠습니다.

 

 

M bit 을 통해 modified 여부를 확인할 수 있으면, 더 효율좋게 Virtual Memory 를 관리할 수 있습니다. 만약 메인 메모리로 로드된 페이지가 Virtual Memory 에 있었을 때와 비교하여 아무 변화가 없다면, 다시 이 페이지를 Virtual Memory 로 내릴 때, 보조 기억장치에 Write 할 필요없이 Main Memory 에서 Clear 하거나 새로운 페이지를 Overwrite 하면 됩니다. 보조 기억장치에서의 I/O 는 속도가 느리기 때문에 이같이 설계하는 것이 효율적입니다.

 

또 Paging 을 이용하여 메모리 관리를 효율적으로 하는 방법이 있습니다.

 

메모장을 2개 띄우는 상황을 생각해봅시다. 메모장에 서로 다른 내용이 들어갈 수는 있지만, 메모장 프로그램이 하는 일은 동일합니다. 이런 상황에 메모장 프로세스를 온전하게 2개 띄우는 것이 효율적일까요? 그보다는, 메모장 프로그램 자체가 갖는 영역은 두 프로세스가 공유하고, 내용을 기록하는 부분은 격리시켜 관리하는 것이 한정된 메모리 자원을 효율적으로 사용하는 방법일 것입니다.

 

이에 대한 설명이 아래 그림에 나타나 있습니다.

 

서로 격리되어야 할 부분인 Data 1, 2, 3 는 별도로 메인 메모리에 올라가며, 공통된 부분인 ed 1,2,3 는 서로 공유하고 있다.

 

그러나 Sharing of Pages 는 Shared Memory 와는 차이점이 있습니다. Shared Memory 는 사용자가 OS 에게 여러 프로세스가 공유할 메모리 공간을 만들어달라고 요청하는 것이지만, Sharing of Pages 는 사용자가 OS 에게 요청하지 않아도 OS 가 알아서 메모리를 효율적으로 관리하기 위해 동작합니다.

 

 

 

 

Demand Paging 방식은 메모리를 효율적으로 관리할 수 있지만, 프로세스가 커지면 Page Table 도 커지는 단점 (Overhead) 이 존재합니다. 이렇게 Page Table 이 커지는 문제를 해결하는 방법인 Multi-level Page Table 에 대해 알아봅시다.

 

Multi-level Page Table

만약 하나의 프로세스의 크기가 4GB 이라면, 페이지의 개수는 100만개 (2^32/2^12) 가 될 것입니다. 그렇다면 PCB 에 저장되는 Page Table 의 크기도 100만 * 4Bytes 가 되겠습니다. 이 경우, Page Table 하나가 Main Memory 상의 하나의 메모리 프레임에 들어갈 수 없게 됩니다.

 

이에 대한 해결책으로 다음과 같은 것들이 있습니다.

 

  • Multi-level Page Table
  • Inverted Page Table (Overhead 가 커서 사용하지 않음)

 

이번 포스팅에서는 Multi-level Page Table 에 대해서 자세히 알아보겠습니다.

 

프로세스 크기에 따라 Page Table Entry 수가 달라짐.

 

 

 

위에서 제시한 문제점 때문에 32 Bits 컴퓨터에서는 2 계층 페이지 테이블을 사용합니다.

 

2계층 페이지 테이블에서는, Page Table Entry 1024 개를 묶어서 하나의 Page 를 만듭니다. 그리고 이 Page 들을 관리하는 Page Table of Page Table 을 만듭니다.

 

 

이 경우 Outer Page Table 이 아닌 Inner Page Table 의 1024 개 Entry 로 이루어진 페이지들은 메인 메모리상에서 연속된 공간에 존재할 필요없이 Logical 하게만 이어져 있으면 됩니다.

 

그렇다면, PCB 에는 Outer Page Table 에 대한 정보를 담고 있으면, 실제 프로세스의 Page 를 찾아갈 수 있습니다.

 

 

2계층 구조를 적용하여 Paging 을 하려면, Logical Address 를 위와 같이 수정해주어야 합니다. 그렇다면 p1 은 Outer Page Table 에서의 Offset, P2 는 Inner Page Table 에서의 Offset, d 는 실제 프로세스의 페이지에서의 Offset 이 되어 Physical Addr 로 접근할 수 있습니다.

 

2계층 페이지 테이블을 이용한 Logical Address -> Physical Address Translation.

 

아까, Demand Paging 방식에서 Logical Addr. 을 Physical Addr. 로 Translation 할 때 Page Table Base Register 의 도움을 받아 빠르게 매핑시킬 수 있다고 했습니다. 이를 2계층 페이지 테이블에 적용하면, Context Swtiching 시 Page Table Base Register 에 Outer Page Table 의 주소만 들어가 있다면, 동일한 방식으로 주소 변환을 수행할 수 있습니다.

 

 

이번에는 Multi-level Demand Paging 에서 Page Table 을 읽는 시간을 줄이는 기술인 Translation Lookaside Buffer (TLB) 에 대해서 알아보겠습니다.

 

Translation Lookaside Buffer (TLB)

Multi-level Page Table 을 사용하게 되면, Memory Access 횟수가 많아집니다. 2계층 페이지 테이블의 경우, Outer Page Table 에 접근할 때 1번, Inner Page Table 에 접근할 때 1번, 실제 프로세스의 페이지에 접근할 때 1번. 총 3번의 Memory Access 를 거쳐야합니다. 

 

메모리 엑세스 횟수가 늘어날 수록, 성능은 저하됩니다. 이러한 점을 극복하기 위해  CPU 내의 고속의 Cache 인 TLB 를 사용합니다. TLB 는 Associative Memory 라고도 불립니다.

 

TLB 는 자주 사용되는 페이지의 페이지 테이블 엔트리를 갖고 있습니다.

 

Direct Mapping 방식에서는 총 2번의 Memory Access 가 발생, TLB 를 사용할 경우, 1번의 Memory Access 발생. (TLB 에 접근하는 것은 CPU 내에서 접근하는 것임. Very Fast)

 

Virtual Address 가 있을 때, 해당 페이지 번호가 TLB 에 있는지 확인합니다. 이 때 하드웨어의 지원을 받아, TLB 내를 순차적으로 훑는 것이 아니라, 병렬적으로 찾아 매우 빠르게 이를 확인할 수 있습니다. TLB 에는 페이지 넘버/페이지 테이블 엔트리 (메인 메모리의 프레임 번호 + Page Control Information) 이 저장되어 있습니다. 따라서, Page Table 과는 다르게 TLB 의 인덱스 번호는 페이지 번호가 아닙니다.

 

Page Table 에서 Page -> Frame 접근과 마찬가지로, TLB 도 Virtual Address 에 해당하는 Page 가 TLB 에 있으면 바로 Frame 으로 접근하고, 해당 Page 가 TLB 에 없으면 페이지 테이블로 가서 확인합니다. 만약 페이지 테이블에도 없으면 페이지 폴트가 일어나겠죠?

 

만약 Process A 의 어떤 Virtual Addr 에 해당하는 Instruction 을 실행할 때, 해당 Virtual Addr 가 속한 Page 에 대한 Page Entry 가 TLB 에 저장되어 있는지 확인했는데 없다면, Page Table 로 가서 해당 페이지가 메인 메모리의 프레임에 로드되어있는지 확인하고, 없다면 Page Fault 가 발생합니다. 

 

그렇다면, Process A 는 Mode Change 후 Page Fault 를 처리하는 명령을 호출하고, .Process A 는 Block(Sleep) 상태가 됩니다. 그리고 다른 프로세스 B 를 Dispatch 후 수행할 것입니다.

 

Page Fault 를 처리하기 위해 Virtual Memory 에서 Page 를 메인 메모리로 가져오면 프로세스 B 가 Mode Change 후 A를 Awake 할 것입니다.

 

과연 TLB 를 이용하면 TLB 를 이용하지 않았을 때보다 빠를까요?  TLB 는 CPU 안에 들어있는 캐쉬이니 더 빠를 것임이 당연하지만, 이를 수학적으로 계산해 봅시다.

 

Effective Access Time

즉, 실질적인 시간이 2보다 작을 것임이 거의 확실하다!

 

 

 

 

Demand Paging 방식에서는 필요한 Page 가 없으면 Page Fault 가 발생하고 보조 기억장치에서 요구되는 Page 를 들고 와야합니다.

 

이 때, 메인 메모리에 빈 공간이 없으면, 메모리 Frame 에 들어있는 Page 중 하나를 골라 보조 기억장치로 내보내고 요구되는 새 Page 를 들고와야합니다.

 

이 때, 내보낼 Frame (Page) 를 고르는 Algorithm 들을 Page Replacement 라고하며 이에 대해 살펴봅시다.

 

 

Page Replacement

 

Page Fault 는 Mode Change 를 필요로하는 Interrupt 이므로 최대한 적게 발생하게 만드는 것이 성능을 위한 좋은 설계입니다.

 

따라서 Page Replacement 를 수행할 때도, 이런 Page Fault 가 적게 발생하도록 수행하여야합니다.

 

그렇다면 어떻게 Page Fault 를 최소화할 수 있을까요? 미래에 가장 적게 호출될 것 같은 Page 를 내보내도록 Replacement Policy 를 설정해야 Page Fault 가 최소화 될 것임을 쉽게 생각할 수 있습니다.

 

그래서 대부분의 Replacement Policy 는 과거의 행동을 기반으로 미래의 행동을 예측하여 Page Fault 를 최소화하도록 합니다.

 

 

먼저, 가장 기본적인 Replacement Algorithm 인 FIFO 에 대해 살펴보겠습니다.

 

FIFO Replacement Policy

 

 

어떤 프로세스에 할당된 메모리 프레임의 개수가 3개라고 가정해봅시다. Reference String 에 따라 각 Page 가 할당/반납 됩니다. FIFO 정책으로 가장 먼저 들어온 페이지를 내보내고 새 페이지를 들여오는 정책으로 Page Replacement 를 수행하면 이 경우 15 번의 Page Fault 가 발생합니다.

 

FIFO 의 경우 구현하기 간단하지만, 곧 다시 Reference 될 Page 도 바로바로 나가게 되는 경향이 있어 그리 좋은 방법은 아닙니다.

 

Optimal Policy

 

가장 적은 Page Fault 를 발생시키는 Optimal Policy 를 살펴봅시다. Optimal Policy 는 Reference String 을 미리 알 수 있어 페이지 폴트가 가장 적게 일어나도록 Replacement 를 수행할 수 있습니다. 하지만 이것은 이론적 비교를 위한 것으로 실제 상황에서 우리는 프로세스가 어떤 순서로 페이지를 요구하는지 즉, Reference String 을 알 수 없기 때문에 이를 구현한 Replacement Policy 를 설정하기는 불가능합니다.

 

LRU (Least Recently Used)

LRU Replacement Algorithm 은 가장 오랜기간동안 Reference 되지 않은 프레임을 내보내는 알고리즘입니다. 이전에 언급했던 Principle of Locality 에 의해 가장 오랜기간 동안 호출되지 않은 프레임은 미래에도 호출되지 않을 가능성이 크기 때문임을 근거로 한 알고리즘입니다.

 

이 알고리즘을 구현하기 위해서는 각 페이지는 마지막 Reference 된 시간이 언제인지 저장하고 있어야합니다. 즉, Overhead 가 있습니다.

 

 

Clock Policy (Second Chance Algorithm)

Clock Policy Algorithm 은 LRU 와 유사하지만, Overhead 는 더 작습니다. 페이지가 처음 메인 메모리에 로드되거나, 호출이 될 때 use bit 을 1로 세팅합니다. 이렇게 하면, 오래동안 사용되지 않은 프레임은 use bit 이 0 이 됩니다. (호출이 되면 use bit 이 1인데  0이라는 말은 호출이 안됐다는 의미겠죠?)

 

그리고 replacement 할 페이지를 고를 때 순차적으로 1로 세팅된 use bit 들을 0 으로 수정합니다. 그래서 처음으로 만나는 0 use bit 인 페이지를 내보냅니다.

 

 

 

아래 그림을 보면 조금 더 쉽게 이해할 수 있습니다.

 

 

이 때, Replacement 를 수행하고 난 다음에 Next Frame Pointer 는 다시 0으로 가지 않고 이어서 움직입니다. 마치 Next - Fit Algorithm 과 유사합니다.

 

 

Enhanced Clock Policy

 

Enhacned Clock Policy 는 Clock Policy 에서 Modified bit (M Bit) 을 추가로 이용하는 Replacement Algorithm 입니다. 메모리에 로드 되었지만 변경 사항이 없는 경우, 프레임을 내보낼 때 보조 기억장치에 Write 를 할 필요가 없습니다. 따라서 

 

1. 오랫동안 사용되지 않았으며

2. 변경사항이 없는 프레임

 

두 조건을 만족하는 프레임이 내보내기에 최적의 프레임인 것을 이용하는 것이 Enhanced Clock Policy 입니다.

 

Replacement Algorithm 별 성능 비교, 모든 페이지를 메인 메모리에 로드할 수 있는 상태라면 Page Fault 를 0 으로 만드는 것도 가능

 

Demand Paging 방식의 퍼포먼스 계산. Swap Page Out Time 은, 변경사항이 없는 프레임을 내보낼 때 그냥 덮어쓰거나 지워버리면 되므로 생략 될 수 있음.

 

 

Thrashing

Virtual Memory 를 사용하고, Demand Paging 방법을 사용하면서 우리는 한정된 메인 메모리 공간안에 더 많은 수의 프로세스를 로드하고 사용할 수 있게되었습니다.

 

메인 메모리에 로드된 프로세스의 수를 Degree of Multiprogramming 이라고 합니다. 이 때, 프로세스 전체가 로드되지 않더라도, 하나의 페이지만 올라와 있어도 됩니다.

 

메인 메모리에 올라와 있는 프로세스가 많을수록, 더 많은 User Process 의 Instruction 을 수행할 수 있으니 CPU Utilization 이 높아질 것임을 쉽게 예상할 수 있습니다.

 

하지만, 아주 많은 수의 프로세스가 올라온 상태 즉, Degree of Multiprogramming 이 아주 큰 상태라면 어떨까요?

 

프로세스 하나가 메인 메모리에서 차지하고 있는 프레임의 수가 아주 적게 될 것이고, 이는 곧 아주 잦은 Page Fault 를 예기할 것입니다.

 

이렇게 User Process 의 Instruction 을 처리하는 것보다 Page Fault 를 처리하는데 더 많은 (Swapping out) 시간을 쏟게 되는 상태를 Thrashing 이라고 합니다.

 

Degree of Multiprogramming 이 커지다보면, 어느 시점에서부터 CPU Utilization 이 오히려 감소하게 된다.

 

 

 

이런 일이 왜 발생하게 되는지 아래 그림을 보며 더 자세하게 분석해 봅시다.

 

 

위 그림에서 타원처럼 생긴 것들은 각 프로세스의 Locality 가 있는 Pages 입니다. 다시 말해, 저 타원 부분의 페이지들은 프로세스를 Execution 할 때 자주 호출되는 부분입니다.

 

No Thrashing 환경에서는 각 프로세스의 Locality 한 페이지들이 메인 메모리에 모두 로드되므로, Page Fault 가 빈번하게 발생하지 않고 프로그램이 실행될 수 있습니다.

 

하지만 Thrashing 이 발생한 환경에서는 각 프로세스의 Locality 한 페이지들이 메인 메모리에 모두 로드될 수 없습니다. 따라서 Page Fault 가 아주 빈번하게 발생하고, 이 인터럽트를 처리하느라 User Instruction 의 처리시간은 감소하게 됩니다. 즉, CPU Utilization 이 감소하게 됩니다.

 

이러한 Thrashing 을 방지하기 위해서 다음과 같은 해결책을 제시합니다.

 

  • Kill Process
  • Process Suspension

 

첫번째 방법은 당연히 효과적이지 않습니다. 중요한 프로세스를 종료시킨다면 큰 문제가 발생할 수도 있겠지요?

 

두번째 방법은 우리가 Process Management 에서 배웠던 Process State 인 Suspended Ready / Suspended Blocked 와 관련이 있습니다.

 

 

즉, Secondary Disk 로 프로세스를 Swap out 시킴으로써, 메인 메모리에 공간을 확보하고 Degree of Multiprogramming 을 감소시켜 Thrashing 을 해결합니다.

 

 

Resident Set

Resident Set 이란, 메인 메모리에 들어와 있는 한 프로세스의 페이지(혹은 프레임)의 집합을 의미합니다.

 

Resident Set 의 Size 란, 메인 메모리에 들어와 있는 한 프로세스의 페이지 (혹은 프레임) 의 수를 의미합니다.

 

위에서 Page Replacement 에 대해 다룰 때, 한 프로세스에 할당된 프레임의 수가 정해져 있는 상황을 이야기한 적 있습니다.

 

그것이 바로 Resident Set 에 대한 이야기입니다.

 

Resident Set Size 를 정하는 방법에는 두가지가 있습니다.

 

  • Fixed-Allocation
  • Variable-Allocation

 

 

Fixed-Allocation 과 Variable-Allocation 의 더 구체적인 방법은 다음과 같습니다.

 

Fixed-Allocation, Local Scope

기본적으로 Fixed-Allocation 은 한 프로세스에게 고정된 수의 메모리 프레임을 할당해줍니다. 따라서 Page Fault 가 발생할 경우, 이 프로세스는 자신이 점유한 메모리 프레임에 들어있는 페이지를 Swap out 하고 새 페이지를 Swap in 해야합니다.

 

Variable-Allocation, Local Scope

Variable-Allocation 은 한 프로세스에 할당할 수 있는 메모리 프레임의 수가 가변적입니다. Local Scope 으로 작동하는 Variable-Allocation 의 겨우, Page Replacement 시 자기 자신의 Page 를 swap out 하다가 Page Fault 의 횟수를 평가하여 운영체제가 그 프로세스가 가질 수 있는 메모리 프레임의 수를 늘리거나 줄일 수 있습니다.

 

Variable-Allocation, Global Scope

한 프로세스가 가질 수 있는 메모리 프레임의 수가 가변적이라는 점은 Local Scope 과 동일하지만, Global Scope 의 경우 Page Fault 가 발생하면 자신의 페이지를 swap out 하는 것이 아닌, 다른 프로세스가 점유하고 있던 메모리 프레임을 가져옵니다. 이 경우, 한 프로세스가 너무 많은 메모리 프레임을 점유하는 경우가 발생할 수 있습니다. 

 

이를 해결하기 위해 운영체제는 Page Frequnecy Scheme 을 이용하여 한 프로세스가 가질 수 있는 메모리 프레임 수를 적절하게 유지하도록합니다.

 

 

OS 는 Page Fault Rate 의 Upper Bound / Lower Bound 를 지정하고, 하나의 프로세스가 이 안에서 Page Fault 가 발생하도록 조절하여 적절한 프로세스 당 적절한 메모리 프레임 수를 유지하도록 합니다.

 

 

 

지금까지 메모리 관리에 대해서 다뤄봤는데, 메모리 관리는 OS 가 적극적으로 수행하지 사용자가 적극적으로 수행하지 않았습니다. 따라서 "개발자는 메모리 관리에 대해 잘 몰라도 되는거 아니야?" 라고 생각하실 수도 있습니다.

 

하지만, 개발자도 메모리 관리에 대한 이해가 필요합니다. 다음은 그 사례 중 하나입니다.

 

 

프로그램에 할당되는 메모리 프레임이 단 1개 라는 가정하에, 정수 1024 * 1024 개를 저장하는 2차원 배열을 생성하고 이를 초기화하는 코드를 작성한다고 생각해봅시다.

 

이 상황에서 배열의 한 행은 메모리 프레임 1개 즉, 4KB 의 크기를 갖습니다.

 

 

Program 1 방식으로 코드를 작성할 경우, Page Fault 가 굉장히 자주 발생하게 되어 성능이 매우 안좋게 됩니다.

 

따라서 개발자는 OS 의 메모리 관리에 대한 이해를 바탕으로 효율적으로 동작할 수 있는 코드를 설계할 수 있도록 해야합니다.

profile

中庸

@짱일모

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!