운영체제(2)

조정훈·2024년 5월 6일

메모리 관리

운영체제의 대표적인 할 일 중 하나가 메모리관리이다.


1. 가상 메모리

가상메모리는 메모리 관리 기법의 하나로 컴퓨터가 실제 이용 가능한 메모리자원을 추상화하여 이를 사용하는 사용자들에게 매우 큰 메모리로 보이게 만드는것이다.
이 때 가상적으로 주어진 주소 = 가상주소, 실제 메모리상에 있는 주소 = 실제 주소 라고한다
가상주소는 메모리관리장치(MMU)에 의해 실제주소로 변환되며 이 덕분에 사용자는 실제 주소를 의식할 필요가 없이 프로그램 구축이 가능하다.
가상메모리는 가상 주소와 실제 주소가 매핑되어있고 프로세스의 주소정보가 들어있는 페이지 테이블 로 관리된다. 이 때 속도 향상을 위해 TLB를 쓴다.

  • TLB : 메모리와 CPU사이에 있는 주소 변환을 위한 캐시. 페이지테이블에 있는 리스트를 보관하며 CPU가 페이지 테이블까지 가지 않도록 해 속도를 향상시킬 수 있는 캐시 계층이다.

스와핑

가상메모리에는 존재하지만 실제메모리(RAM)에 없는 데이터나 코드에 접근할 경우 페이지폴트가 발생한다. 이 때 메모리에서 당장 사용하지 않는 영역을 하드디스크로 옮기고 하드디스크의 일부분을 마치 메모리처럼 불러와 쓰는 것을 스와핑이라고한다.
이를 통해 마치 페이지폴트가 일어나지 않은 것처럼 만든다.


페이지 폴트

프로세스의 주소 공간에는 존재하지만 지금 이 컴퓨터의 RAM에는 없는 데이터에 접근했을 경우에 발생.
과정

    1. 어떤 명령어가 요휴한 가상 주소에 접근했으나 해당 페이지가 없다면 트랩이 발생되어 운영체제에 알림
    1. 운영체제는 실제 디스크로부터 사용하지 않은 프레임을 찾는다
    1. 해팡 프레임을 실제 메모리에 가져와서 페이지 교체 알고리즘을 기반으로 특정 페이지와 교체(이 때 스와핑)
    1. 페이지 테이블을 갱신시킨 후 해당 명령어를 다시 시작한다.

페이지 : 가상메모리를 사용하는 최소 크기 단위
프레임 : 실제 메모리를 사용하는 최소 크기 단위


2. 스레싱

스레싱(thrashing)은 메모리의 페이지 폴트율이 높은것을 의미하며 이는 컴퓨터의 심각한 성능저하를 일으킨다.
메모리에 너무 많은 프로세스가 동시에 올라가게 되면 스와핑이 많이 일어나서 발생한다.
페이지폴트가 일어나면 CPU이용률이 낮아짐. 이렇게 되면 CPU가 한가하다고 생각해서 가용성을 더 높이기위해 더 많은 프로세스를 메모리에 올리게된다. 이렇게 악순환이 반복되며 스레싱이 일어난다.
이를 해결하기 위해서는 메모리를 늘리거나, HDD대신 SSD로 바꾸는방법이있다. 이외에 운영체제에서 이를 해결할 수 있는 방법은 작업세트와 PFF가 있다.


작업세트

작업세트(working set)는 프로세스의 과거 사용이력인 지역성을 통해 결정된 페이지 집합을 만들어서 미리 메모리에 로드하는것이다. 미리 메모리에 로드하면 탐색에 드는 비용을 줄일 수 있고 스와핑 또한 줄일 수 있다.


PFF

PFF(Page Fault Frequency)는 페이지 폴트 빈도를 조절하는 방법으로 상한선과 하한선을 만드는 방법이다. 만약 상한선에 도달한다면 프레임을 늘리고 하한선에 도달한다면 프레임을 줄인다.



3. 메모리 할당

메모리에 프로그램을 할당할 때는 시작메모리위치, 메모리의 할당크기를 기반으로 할당하는데 연속할당, 불연속할당으로 나뉜다.

연속 할당

메모리에 연속적으로 공간을 할당하는 것.
그림처럼 프로세스A, B, C가 순차적으로 공간에 할당하는걸 예시로 볼 수 있다.
이렇게 메모리를 미리 나누어 관리하는 고정분할방식과 매 시점 프로그램의 크기에 맞게 메모리를 분할하여 사용하는 가변분할방식이 있다.


고정 분할 방식

고정분할방식(fixed parition allocation)은 메모리를 미리 나누어 관리하는 방식이며, 메모리가 미리 나뉘어 있기 때문에 융통성이 없다. 또한 내부단편화가 발생한다.

가변 분할 방식

가변분할방식(variable partition allocation)은 매 시점 프로그램의 크기에 맞게 동적으로 메모리를 나눠 사용한다. 내부 단편화는 발생하지 않고 외부 단편화는 발생할 수 있다. 이는 최초적합, 최적적합, 최악적합이 있다.

내부단편화 : 메모리를 나눈 크기보다 프로그램이 작아서 들어가지 못하는 공간이 많이 발생하는 현상

외부단편화 : 메모리를 나눈 크기보다 프로그램이 커서 들어가지 못하는 공간이 많이 발생하는 현상.

홀 : 할당할 수 있는 비어있는 메모리 공간


불연속 할당

메모리를 연속적으로 할당하지 않는 불연속 할당은 현대 운영체제가 쓰는 방법으로, 불연속 할당인 페이징 기법이 있다. 메모리를 동일한 크기의 페이지로 나누고 프로그램마다 페이지 테이블을 두어 이를 통해 메모리에 프로그램을 할당하는 것이다. 페이징 기법 말고도 세그멘테이션, 페이지드 세그멘테이션 등이 있다.


페이징

동일한 크기의 페이지 단위로 나누어 메모리의 서로 다른 위치에 프로세스를 할당한다.
홀의 크기가 균일하지 않은 문제가 없어지지만 주소 변환이 복잡해진다.

세그멘테이션

페이지 단위가 아닌 의미 단위인 세그멘트로 나누는 방식. 프로세스를 이루는 메모리는 코드영역, 데이터영역, 스택영역, 힙영역으로 이루어지는데 코드와 데이터로 나누거나 코드 내의 작은 함수를 세그먼트로 놓고 나눌수도있다. 이는 공유와 보안 측면에서 장점이 있지만 홀 크기가 균일하지 않다는 단점이 있다.

페이지드 세그멘테이션

프로그램을 의미 단위인 세그먼트로 나눠 공유나 보안 측면에 강점을 두고 임의이 길이가 아닌 동인할 크기의 페이지 단위로 나누는것을 말한다.



4. 페이지 교체 알고리즘

메모리는 한정되어 있기 때문에 스와핑이 많이 일어나게된다. 스와핑이 많이 일어나지 않도록 설계되어야 하며 이는 페이지 교체 알고리즘을 기반으로 스와핑이 일어난다.

오프라인 알고리즘

먼 미래에 참조되는 페이지와 현재 할당되는 페이지를 바꾸는 알고리즘이며 가장 좋은방법이다. 그러나 미래에 사용되는 프로세슬를 미리 알수가 없다.
즉 사용할 수 없는 알고리즘이지만 가장 좋은 알고리즘이기 때문에 다른 알고리즘과의 성능비교에 대한 상한기준을 제공한다.

FIFO

First In First out . 선입선출방식. 가장 먼저 온 페이지를 교체 영역에 가장 먼저 놓는 방법을 의미한다.

LRU

Least Recently Used. 참조가 가장 오래된 페이지를 바꾼다. 오래된 것을 파악하기 위해 각 페이지마다 계수기, 스택을 두어야하는 문제점이 있다.

LRU 구현을 프로그래밍으로 할 때 보통 두 개의 자료구조로 구현한다. 바로 해시테이블, 이중연결리스트 이다. 해시테이블은 이중연결리스트에서 빠르게 찾을 수 있도록 쓰고, 이중연결리스트는 한정된 메모리를 나타낸다.

NUR

Not Used Recently.LRU에서 발전한 알고리즘

일명 clock알고리즘이라고 하며 먼저 0과 1을 가진 비트를 둔다.
1 : 최근에 참조되었음
0 : 참조되지않음
시계방향으로 돌면서 0을 찾고 0을 찾은 순간 해당 프로세스를 교체하고, 해당 부분을 1로 바꾸는 알고리즘

LFU

Least Frequently Used. 가장 참조 횟수가 적은 페이지를 교체한다. 즉, 많이 사용되지 않는 것을 교체하는것




프로세스와 스레드

프로세스 : 컴퓨터에서 실행되고 있는 프로그램을 말하며 cpu 스케줄링의 대상이 되는 작업(task)라는 용어와 거의 같은 의미로 쓰인다.
스레드 : 프로세스 내 작업의 흐름

앞의 그림처럼 프로그램이 메모리에 올라가면 프로세스가 되는 인스턴스화가 일어나고, 이후 운영체제의 CPU스케줄러에 따라 CPU가 프로세스를 실행한다.


프로세스와 컴파일 과정

프로그램은 chrome.exe 와 같은 실행파일이고 이를 두 번 클릭하면 구글 크롬프로세스로 변환되는 것이다.
프로그램을 만드는 과정은 언어마다 다를 수 있고 컴파일 언어인 C언어 기반의 프로그램을 기준으로 설명하면 컴파일러가 컴파일 과정을 통해 컴퓨터가 이해할 수 있는 기계어로 번역하여 실행할 수 있는 파일을 만들게 된다.

컴파일과정


전처리

소스 코드의 주석을 제거하고 #include등 헤더 파일을 병합하여 매크로를 치환

컴파일러

오류처리, 코드최적화 작업을 하며 어셈블리어로 변환한다

어셈블러

어셈블리어는 목적 코드(object code)로 변환된다. 이 때 확장자는 운영체제마다 다른데 리눅스 는 .o 이다. 예를들어 가영.c 라는 파일을 만들 때 가영.o 라는 파일이 만들어지게 된다.

링커

프로그램 내에 있는 라이브러리 함수 또는 다른 파일들과 목적코드를 결합하여 실행파일을 만든다. 실행 파일의 확장자는 .exe , .out

라이브러리

라이브러리는 동적, 정적라이브러리로 나뉜다

정적라이브러리

프로그램 빌드 시 라이브러리가 제공하는 모든 코드를 실행 파일에 넣는 방식으로 라이브러리를 쓰는 방법. 시스템 환경 등 외부 의존도가 낮은 장점이 있지만 코드 중복 등 메모리 효율성이 떨어진다는 단점이 있다.

동적라이브러리

프로그램 실행 시 필요할 때만 DDL이라는 함수 정보를 통해 참조하여 라이브러리를 쓰는 방법. 메모리 효율성에서의 장점을 지니지만 외부 의존도가 높아진다는 단점이 있다.



프로세스의 상태

생성 상태

프로세스가 생성된 상태를 의미하며 fork() 또는 exec() 함수를 통해 생성한다. 이때 PCB가 할당된다.

fork()

부모 프로세스의 주소공간을 그대로 복사하며, 새로운 자식 프로세스를 생성하는 함수이다. 주소 공간만 복사할 뿐이지 부모 프로세스의 비동기 작업 등을 상속하지는 않는다.

대기 상태

대기상태는 메모리 공간이 충분하면 메모리를 할당받고 아니면 아닌 상태로 대기하고 있으며 CPU스케줄러로부터 CPU 소유권이 넘어오기를 기다리는 상태이다.

대기 중단 상태

대기 중단 상태는 메모리 부족으로 일시 중단된 상태이다.

실행 상태

CPU소유권과 메모리를 할당받고 인스트럭션을 수행 중인 상태를 의미. CPU burst가 일어났다고도 한다.

중단 상태

어떤 이벤트가 발생한 이후 기다리며 프로세스가 차단된 상태.
I/O 디바이스에 의한 인터럽트로 이런 현상이 많이 발생하기도 한다.
예를들어 프린트 인쇄 버튼을 눌렀을 때 프로세스가 잠깐 멈춘듯 할때가 바로 이상태이다.

일시 중단 상태

대기 중단과 유사하다. 중단된 상태에서 프로세스가 실행되려고 했지만 메모리 부족으로 일시 중단된 상태.

종료 상태

메모리와 CPU 소유권을 모두 놓고 가는 상태. 종료는 자연스럽게 종료되는것도 있지만 부모 프로세스가 자식 프로세스를 강제시키는 자발적종료(abort)로 종료되는것도 있따. 자식 프로세스에 할당된 자원의 한계치를 넘어서거나 부모 프로세스가 종료되거나 사용자가 process, kill등 여러 명령어로 프로세스를 종료할 떄 발생한다.

0개의 댓글