## 목차 ##
## 1. 메모리 관리의 개요 ##
(1) 메모리 관리의 복잡성
메모리의 '워드'란 메모리에 저장되는 데이터의 크기를 가리킨다.
- 아래 그림은 메모리 워드가 1byte인 메모리 모습이다.
메모리의 워드마다 주소(번지)가 붙는다.
메모리는 유일한 작업공간이다.
- 모든 프로그램은 메모리에 올려야 실행이 가능하다.
메모리 관리의 복잡성
- 시분할 시스템에서는 운영체제를 포함한 여러 응용프로그램이 메모리에 올라와 실행되기때문에 메모리 관리가 복잡하다.
메모리 관리는 메모리 관리 시스템(Memory Management System)이 담당한다.
(2) 메모리 관리의 이중성
메모리 관리의 이중성
- 프로세스는 메모리를 독차지하려하고 관리자는 메로리를 효율적으로 관리하고 싶어하는 문제
- 프로세스 입장에서 작업의 편리함과 관리자 입장에서 관리의 편리함이 충돌
- 둘의 상충되는 요구사항을 처리해야한다.
한정된 메모리에서 여러 작업을 동시에 실행해야 하는 문제에서 비롯되었다.
(3) 소스코드의 번역과 실행
언어 번역 프로그램
- 고급 언어(C, Java 등)으로 작성한 소스코드를 컴퓨터가 실행할 수 있는 저급 언어(어셈블리어, 기계어)로 번역하는 프로그램이다.
- 컴파일러(compiler), 인터프리터(interpreter)
컴파일러
- 소스 코드를 기계어로 번역 후 한꺼번에 실행한다.
- C언어, Java 등
- 오류를 발견하여 실행 시 문제가 없도록 한다.
- 실행 전에 코드를 점검하여 오류를 수정하고 최적화함으로써 작고 빠른 실행 파일을 만든다.
컴파일러의 목적
- 오류 발견(오류를 찾기위해 심볼 테이블 사용)
- 코드 최적화(미리 코드 전체를 보고 이를 최적화)
인터프리터
- 소스코드를 한 행씩 번역하여 실행한다.
- 자바스크립트, 파이썬 등
- 한 줄씩 실행되기 때문에 컴파일러처럼 실행 전 최적화가 불가능하다.
- 컴파일러에 비해 비교적 소형이고 간단한 프로그램에 사용한다.
컴파일 과정
- 컴파일하여 목적코드 생성
- 라이브러리를 연결하여 최종 실행파일 생성(링커)
- 실행시에 실행 코드를 라이브러리에서 가져와 실행한다.(동적 라이브러리 로딩)
(4) 메모리 관리자의 역할
메모리 관리를 하는 하드웨어 유닛
- 가져오기(fetch)
- 배치(placement)
- 재배치(replacement)
가져오기
- 프로세스와 데이터를 메모리로 로드
- 용량이 큰 데이터는 일부씩 여러번 가져와 실행
- 필요할 것이라고 예상되는 데이터를 미리 로드하기도 한다.(선인출 prefetch)
- 언제 메모리로 가져올지 결정하는 '가져오기 정책'을 따른다.
배치
- 프로세스나 데이터를 어느 위치에 넣을지 결정하는 작업
- 메모리를 어떤 크기로 자를지가 매우 중요
- 어떤 위치에 올릴지 결정하는 '배치 정책'을 따른다.
- 메모리를 같은 크기로 자르는 고정 분할 방식
- 메모리를 프로세스 크기에 맞게 자르는 가변 분할 방식
재배치
- 메모리가 꽉 찬 경우 새로운 프로세스를 로드하기 위해 오래된 프로세스를 내보내는 작업
- 재배치 기준을 따른다.
- 어떤 프로세스를 메모리에서 내보낼지 결정하는 '재배치 정책'을 따른다.
- 재배치 정책에서 사용하는 알고리즘을 교체 알고리즘이라고 한다.
## 2. 메모리 주소 ##
(1) 절대 주소와 상대 주소
메모리 영역의 구분
- 운영체제 영역과 사용자 영역을 구분하여 사용
- 사용자 프로세스가 운영체제의 영역을 침범하는 일을 막기 위해 경계 레지스터 사용
- 메모리 관리자는 사용자 요청이 경계 레지스터의 값을 벗어나는지 검사(벗어나면 프롤세스 종료 요청)
절대 주소와 상대 주소의 개념
- 절대 주소는 메모리 관리자가 바라보는 주소이자 실제 메모리의 물리적 주소
- 상대 주소는 사용자 프로세스 입장에서 바라보는 주소이며 0번지부터 시작
- 상대 주소를 사용하는 주소 공간을 논리 주소 공간이라고 한다.
- ex) 운영체제가 399번지까지 사용하면 프로세스는 400번지부터 적재되기 시작하므로 상대주소가 100번지라면 실제 물리 메모리의 절대 주소는 500번지이다.
프로세스를 실행할 때 메모리 관리자는 재배치 레지스터를 사용하여 상대주소를 물리주소로 변환하여 사용한다.
## 3. 단일 프로그래밍 환경에서의 메모리 할당 ##
(1) 메모리 오버레이
- 크기가 큰 프로그램을 적당한 크기로 잘라(여러 모듈로 나눔) 필요한 모듈만 메모리에 올려 사용하는 기법
프로그램 전체를 메모리에 올리는 것보다 느리지만 메모리가 프로그램보다 작을 때도 실행 가능
PC(프로그램 카운터)에 로드 된 명령어에서 필요한 모듈이 메모리에 없으면 메모리 관리자에 요청한다.
가상 메모리의 기본이 되는 개념
(2) 스왑
- 메모리가 모자라서 쫓겨난 프로세스는 하드디스크의 스왑 영역(swap area)에 저장된다.
- 스왑 인(swap in), 스왑 아웃(swap out)
- 스왑 영역은 메모리 관리자가 관리한다.
- 저장장치는 공간만 빌려준다.
- ex) 최대 절전 모드는 PC 전원을 OFF하면서 현재 메모리의 데이터를 스왑 영역에 저장해둔다.
- Windows, Unix 계열의 운영체제는 스왑 영역을 디스크의 일부분에 따로 할당해둔다.
- Unix 계열 운영체제에서는 free 명령어로 스왑 영역의 크기를 확인할 수 있다.
- Unix 계열 운영체제는 일반적으로 스왑 영역의 크기를 메모리의 2배 정도로 잡는다.
## 4. 다중 프로그래밍 환경에서의 메모리 할당 ##
(1) 메모리 분할 방식
고정 분할 방식
- 메모리 영역을 미리 고정된 크기의 여러 파티션으로 나누어놓는 방식
- 큰 프로세스는 여러 영역에 나누어 할당
- 큰 프로세스의 경우 연속적이지 않은 메모리 공간에 배치될 수 있어 효율성 감소
- 메모리 관리가 효율적이고 수월하다.
- 파티션보다 작은 프로세스의 경우 메모리 낭비 발생
- 현대 운영체제는 기본적으로 고정 분할 방식이면서 일부분은 가변 분할 방식을 사용
가변 분할 방식
- 프로세스의 크기에 따라 메모리를 할당하는 방식
- 한 프로세스가 연속된 공간에 배치되어 메모리 관리 효율성 증가
- 메모리 관리가 복잡
(2) 가변 분할 방식의 메모리 관리
- 외부 단편화
- 프로세스가 들어갈 수 있는 크기가 되지않는 여러 작은 빈 조각들이 발생하는 현상(외부 단편화)
메모리 배치 방식
- 외부 단편화를 해결하기 위해 프로세스를 배치하는 방식
- 최초 배치, 최적 배치, 최악 배치, 버디 시스템
최초 배치(First Fit)
- 프로세스 적재 가능한 공간을 순서대로 찾다가 첫 번째로 발견한 공간에 프로세스를 배치
최적 배치(Best Fit)
- 빈 공간을 모두 확인 후 가능한 가장 작은 공간에 프로세스를 배치
- 딱 맞는 크기가 없을 경우 외부 단편화로 인한 조각은 작을 것이고 쓸모가 없을 가능성이 높다.
최악 배치(Worst Fit)
- 빈 공간을 모두 확인 후 가장 큰 공간에 프로세스를 배치
- 프로세스를 배치하고 남은 공간이 커 쓸모가 있다.
- 조각 모음
- 배치 방식을 사용해도 단편화는 발생한다.
- 조각 모음은 서로 떨어져 있는 빈 조각들을 합치는 작업이다.
- 조각 모음을 위해 프로세스를 중지시키고, 이동하고, 주소를 바꾸고, 다시 시작해야하는 추가작업 필요
- 하드디스크에서도 외부 단편화는 발생하여 조각모음을 주기적으로 실행해주는것이 좋다.
(3) 고정 분할 방식의 메모리 관리
- 내부 단편화
- 파티션 크기보다 작은 프로세스의 경우 낭비되는 공간 발생
- 조각 모음을 할 수 없고 다른 프로세스가 사용하는 것도 불가능
- 분할되는 공간의 크기를 조절하여 내부 단편화를 최소화
(4) 버디 시스템
가변 분할 방식의 외부 단편화를 완화하는 방법
가변 분할 방식과 고정 분할 방식의 중간 구조
- 프로세스 크기에 맞게 1/2로 메모리를 잘라 나간다.
- 프로세스에 맞는 적당한 크기가 되었을 때 프로세스를 배치한다.
- 나뉜 메모리의 각 구역에는 프로세스 1개만 들어간다. 구역내에 빈 자리가 있어도 다른 프로세스가 사용하지 않는다.
- 프로세스가 종료되면 주변의 빈 조각과 합쳐서 하나의 큰 덩어리를 만든다.
비슷한 크기의 덩어리가 인접한 위치에 존재하기 때문에 통합이 쉽다.
- 가변 분할에서는 큰 프로세스 사이에 존재해 조각모음을 하기위해 프로세스를 옮겨야한다.
- 조각 모음을 하지 않아도 큰 덩어리를 만들 수 있다.
그러나 메모리 관리 효율 측면에서는 고정 분할 방식이 더 단순하여 고정 분할 방식이 많이 사용된다.
## 5. 컴파일과 메모리 관리 ##
(1) 컴파일 과정
- 고급 언어의 소스코드를 번역하여 목적코드 생성
- 오류가 있는지 점검하고 최적화를 통해 필요 없는 변수와 코드를 삭제
- 목적 코드에 라이브러리 코드를 삽입하여 최종 실행 파일 생성(링크)
(2) 변수와 메모리 할당
- 컴파일 과정에서 메모리를 확보하고 정리
- 심볼 테이블(symbol table) 사용
- 모든 변수는 메모리 주소로 바뀌어 저장된다.
- 변수는 단지 프로그래머의 편의성을 위한 것이다.
'CS > 운영체제' 카테고리의 다른 글
(운영체제) 9 - 가상 메모리 관리 (0) | 2020.05.15 |
---|---|
(운영체제) 8 - 가상 메모리의 기초 (0) | 2020.05.15 |
(운영체제) 6 - 교착 상태(데드락) (0) | 2020.05.15 |
(운영체제) 5 - 프로세스 동기화 (0) | 2020.05.15 |
(운영체제) 4 - CPU 스케줄링 (0) | 2020.05.15 |