Little Jay

[OS] Memory Management I 본문

Univ/Operating System(OS)

[OS] Memory Management I

Jay, Lee 2022. 12. 28. 15:11

Terminology

 메모리에 대한 이야기를 하기에 앞서서 용어를 간단하게 정리하고 넘어가겠다. 

  • Static Allocation(고정할당): Program이 execute되기 전에 메모리를 할당한다. Pre-defined된 static이나 global variable등을 선언하면 compile time에 결정이 된다.
  • Dynamic Allocation(동적할당): run time에 메모리가 할당되는 것이다. 필요에 의해서 할당이 되는 것이며 주로 memory의 Heap 영역을 사용하는 malloc, new 등이 이에 대당이 된다. Memory가 미래에 얼마나 사용이 될지 모르기에 이를 사용한다. 

Memory Management

 Main Memory는 크게 두 가지의 파트로 나뉜다. 첫 번째는 OS를 위한 영역이다. OS라고 함은 resident하고 이는 monitor, kernel등을 의미한다. 즉 이 Kernel이 올라가있는 부분이라고 이해하면 편하겠다. 다음으로는 user part를 위한 영역이다. user라고 하는 것은 단순히 사용자를 의미한다고 보면 되겠다. Program은 결국 user가 만드는 것이기 때문에 다수의 Process를 위해 Subdivision하게 된다. 물론 Uni-Programming이라면 하나의 Process만 올라가게 된다. 

 Task of Subdivision, 다시말해 Memory Management는 동적으로 OS에 의해 실행이 되며 OS는 Memory를 분할하는 역할을 수행하게 된다. 이 Memory Management는 Multiprogramming의 핵심 기능이라고 볼 수 있다. 

Memory Management Requirements

 그렇다면 Memory Management의 요구사항은 어떤 것이 있을지 차례로 확인해보자. 

1. Relocation 

 메인메모리는 하나의 컴퓨터 자원으로서 HW이다. 이는 모든 Process가 공유하는 자원이다. Process의 입장에서는 Program이 Compile될때 Memory의 어떤 곳에 위치할 지 모른다. 요새 사용하고 있는 메모리는 대부분 16GB인데 이 엄청나게 긴 Byte Address의 어떤 곳에 위치할 지는 Program은 모른다. 또한 올라간다고 하더라도, CPU의 Maximum Utilization을 위해 또 이 Process는 이동될 수 있다. 따라서 이런 기능의 위해 Relocation, 다시 말해 재배치라는 기능이 필요하다. 이는 보통 MMU(Memory Management Unit)이라는 HW적인 지원을 해준다. 이에 대해서는 뒤에 가서 다뤄볼 것이다. 

2. Protection

 각각의 Process는 수행 시 다른 Process들이 자신의 Memory 영역에 침범하지 않도록 방해를 받으면 안된다. 다시말해서 각 Process에게 할당된 Memory Space만 사용할 수 있도록 보장해야한다. Process Image라는 것을 복기해보면 Process는 Stack, Heap, Code, Data 영역으로 이루어져 있다. 이 고정된 영역을 다른 Process가 침범하게 된다면 Memory에 올라간 Program은 당연히 Malicious할 것이다. 따라서 이를 위해 Bound Register가 존재하며 이 범위를 넘어가게 되면 Abort된다. Relocation에서도 보았듯이, 우리는 Program에서 Memory의 Absolute Address를 예측할 수 없다. 그렇다면 Protection은 어떻게 보장하는 것인가에 대한 의문이 들 수 있다. 이는 Dynamic Translation of Address를 통해 해결할 수 있다. HW의 Kernel Level에서 구현됨으로서 Run Time에 이를 적절히 바꾸고 할당하면 Protection은 적절히 구현될 수 있다. 

3. Sharing

 Protection Mechanism은 여러개의 Process가 메인 메모리라는 공유자원을 동시에 접근할 수 있도록 Flexibility를 제공해줘야한다. 다수의 Process가 동일한 Program을 싱행하거나 Library를 사용할 때 Copy본을 만들면 이는 명백히 자원에 대한 낭비이다. 따라서 각 Process마다 Copy본을 만드는 것이 아니라, Shared Memory에 넣고 접근할 수 있도록 지원해야 한다. Kernel, Code, Data 모두 Shared Memory에 올리는 것이 좋을 것이다. Linux의 IPC중 Shared Memory로 구현이 가능하다. 

4. Logical Organization

 메모리를 배울 때 주의해야 하는 것은 Actual Physical Memory와 Program의 Organization은 서로 다르다는 것이다. Actual Physical Memory는 다시 말해서 Main Memory(DRAM)인데 얘는 Random Access가 가능한 Byte Addressable한 HW이다. 그러나 Memory를 사용하는 측면에서는 조금 주의해야 할 필요가 있는데 앞서서도 언급을 했지만 Program은 Code, Data, Heap, Stack으로 관리가 되는데 이러한 구조를 Logical View라고 한다. 이 Logical한 View로 Program이 메모리를 활용하는 것이다. 그러나 메모리 그 자체의 입장에서는 어떤 Program이 이러한 Module로 구성되고 구현하는지 전혀 모른다. 이러한 Logical한 Module로 구분한다면 울는 그 특성에 맞게 자원을 관리할 수 있다. 예를 들어서 Code 영역은 Memory에 다시 Program을 올리지 않는 한 수정되지 않고 실행만 할 수 있다. Heap과 Stack은 자원을 저장만 하는 공간으로서 수정은 자유롭지만 실제 이를 수행을 하지는 않는다. 기존의 Base & Bound Register을 사용하게 된다면 이 영역에 대한 Size를 딱 고정해놓아서 Internal Fragmentation(내부 단편화)의 문제가 생긴다. 그러나 각 Segment, 다시말해 각 영역의 Bound와 Base를 각각 구성한다면 내부 단편화를 줄일 수 있고, 그 공간을 General하고 Effective하게 사용할 수 있다. 지금 당장 Segmentation에 대한 이해가 어려울 수 있는데, 자세한 내용은 뒤에 가서 또 언급할 것이다. Segmentation을 배우면 이 내용이 논리적으로 이해가 될 것이다. 

5. Physical Organization

  컴퓨터에서 Memory 계층은 2개 이상으로 구성이 된다(Primary, Secondary......) 물리적으로 Secondary Memory의 도움을 받아야 효율적으로 관리가 가능하다. 예를 들자면 모든 Program이 Memory에 올라갈 필요는 없다. 오히려 모든 Program이 Memory에 올라간다면 오히려 Page Fault가 계속 발생하여 컴퓨터의 성능이 떨어질 것이다. 따라서 필요하 부분만 수행함으로서 메모리를 효율적으로 사용해야 한다. 

Types of Addresses

 주소의 종류는 크게 2개, 세분화 하면 3개로 나눌 수 있다. 먼저 Logical Address가 있다. 경우에 따라서 Relative Address, Virtual Address라고도 불리는데 Process에서의 location을 의미한다. Process의 시작점을 0으로 하고 Process의 offset을 계산한다. 그러나 실제로 Memory에 올라간다면 Physical Address로 변환해햐 한다. 메모리 상에 실제하지 않는 주소를 있는 것 처럼 사용하는 것, 이것이 바로 Virtual이다. 이와 정 반대 되는 주소는 Physical Address이다. Absolute Address라고도 부리는데 실제 메모리 상의 주소를 의미한다. Address Translation은 Dynamic하게 일어나며 현대에는 MMU로 처리한다는 것을 기억해두자. 마지막으로는 Symbolic Address는 소스코드의 주소이다. 변수, instruction code, src code 등이 이에 해당한다. ELF Format을 사용한다면 Symbolic Address도 중요하게 사용된다. 

Address Space 

 Address Space는 Process가 Memory를 바라보는 View이다. 즉 이는 Logical Address이다. Program을 Compile하게 되면 Assembly Code로 바뀌게 되는데 이때 사용하는 주소는 Logical Address이다. Physical Address로 바뀌는 시점은 Execution 시점이다. 따라서 Process에서는 Transparent 한 방식을 사용한다. 이 방식은 단순히 숨김 기능이라고 생각하면 된다. 존재하지만 관리의 효율성을 위해서 숨겨주는 설계 철함이다. 이는 Virtual과는 반대되는 것이다. 이 방식은 Dynamic Address Translation에서 잘 사용이 된다. MMU에서 다 알아서 Physical Address로 변환을 하지만 이 Translation과성을 Process가 알지 못하며 또한 알 필요가 없다. 따라서 Process는 Logical Address만 알 뿐 Physical Address는 전혀 알지 못한다. 

Comments