Post

물리 메모리 관리

메모리 관리의 개요

메모리 관리의 복잡성

메모리의 구조는 1B 크기로 나뉘고 각 영역은 메모리 주소로 구분한다.

CPU는 메모리에 있는 내용을 가져오거나 작업 결과를 메모리에 저장하기 위해 메모리 주소 레지스터를 사용한다.

메모리 관리의 이중성

메모리 관리의 이중성은 프로세스 입장에서 작업의 편리함과 관리자 입장에서 관리의 편리함이 충돌을 일으키는 것을 말한다.

SSD와 같은 빠르고 큰 저장장치가 있는데 왜 굳이 프로그램을 메모리에 가져와서 실행하는 것일까? 느리고 값싼 하드디스크는 제2 저장장치로 사용하고 비싸고 빠른 메모리는 작업 공간으로 사용한다. 같은 맥락에서 메모리보다 용량은 작지만 속도가 빠른 캐시 메모리를 추가로 사용한다. 캐시 메모리는 몇 메가바이트 밖에 안 되지만 CPU 속도로 작동하여 전체 시스템의 작업 속도가 빨라진다. 이렇게 메모리를 계층적 구조로 만들어 작업 속도를 올리고 가격을 낮추는 방법을 계층적 메모리 구조라고 한다.

소스코드의 번역과 실행

기계어와 어셈블리어는 컴퓨터의 동작을 가장 직접적으로 표현한 언어로 저급 언어라고 한다.

저급 언어와 반대되는 개념인 고급 언어는 사용자가 이해하기 쉽게 프로그래밍할 수 있는 언어로, C 언어와 자바가 대표적인 예이다.

언어 번역 프로그램은 고급 언어로 작성한 소스코드를 컴퓨터가 실행할 수 있는 기계어로 번역하는 프로그램이다.

  • 컴파일러 : 소스코드를 컴퓨터가 실행할 수 있는 기계어로 번역한 후 한꺼번에 실행한다. ex) C 언어, 자바
  • 인터프리터 : 소스코드를 한 행씩 번역하여 실행한다. ex) 자바스크립트, 베이직

컴파일러의 목적

  • 오류 발견

컴파일러는 오류를 찾기 위해 심벌 테이블을 사용한다.

심벌 테이블은 변수 선언부에 명시한 각 변수의 이름과 종류를 모어놓은 테이블로, 선언하지 않은 변수를 사용하지는 않았는지, 변수에 다른 종류의 데이터를 저장하지는 않았는지 알 수 있다.

  • 코드 최적화

레시피에서 ‘당근 1개를 잘라서 볶는다’가 두 번 나온다면 이를 ‘당근 2개를 잘라서 볶는다’로 변경하여 작업을 줄일 수 있다.

또한 준비 재료에는 쓰여 있지만 실제 요리에 사용하지 않는 ‘고추’를 삭제하여 불필요한 재료를 없앨 수 있다.

소스코드도 마찬가지로 군더더기와 사용하지 않는 변수를 삭제하면 더욱 간결해져서 실행 속도가 빨라진다.

결론적으로 컴파일러는 실행하기 전에 코드를 점검하여 오류를 수정하고 최적화함으로써 작고 빠른 실행 파일을 만든다.

컴파일러와 인터프리터의 차이

구분자바자바스크립트
변수변수를 선언해야 한다.변수를 선언할 필요가 없다.
실행컴파일 후 실행된다.한 줄씩 실행된다.
장점오류 찾기와 코드 최적화, 분할 컴파일에 의한 공동 작업이 가능하다.실행이 편리하다.
사용 프로그램대형 프로그램간단한 프로그램

컴파일 과정

  • 소스코드 작성 및 컴파일
  • 목적 코드와 라이브러리 연결
  • 동적 라이브러리를 포함하여 최종 실행

메모리 관리자의 역할

  • 가져오기 : 메모리 관리자는 사용자가 요청하면 프로세스와 데이터를 모두 메모리로 가져온다.
  • 배치 : 메모리의 구역을 나눠 가져온 프로세스와 데이터를 올려놓는다. 메모리를 같은 크기로 자르는 것을 페이징이라고 하며, 프로세스의 크기에 맞게 자르는 것을 세그먼테이션이라고 한다.
  • 재배치 : 꽉 찬 메모리에 새로운 프로세스를 가져오기 위해 오래된 프로세스를 내보내는 작업

메모리 주소

32bit CPU와 64bit CPU의 차이

CPU의 비트는 한 번에 다룰 수 있는 데이터의 최대 크기를 말한다.

64bit CPU는 레지스터의 크기, 버스의 대역폭, 한 번에 처리되는 데이터의 최대 크기 등이 32bit CPU의 2배이다.

따라서 32bit CPU보다 처리 속도가 빠르고 사용할 수 있는 메모리도 크다.

32bit CPU든 64bit CPU든 컴퓨터에는 메모리가 설치되며 각 메모리 주소 공간이 있다.

이렇게 설치된 메모리의 주소 공간을 물리 주소 공간이라고 하며 이와 반대로 사용자 입장에서 바라본 주소 공간은 논리 주소 공간이라고 한다.

절대 주소와 상대 주소

메모리 영역의 구분

메모리 관리자는 메모리를 운영체제 영역과 사용자 영역으로 나누어 관리한다.

사용자 영역이 운영체제 영역으로 침범하는 것을 막으려면 하드웨어의 도움이 필요한데, 이는 CPU 내에 있는 경계 레지스터가 담당한다.

경계 레지스터는 운영체제 영역과 사용자 영역 경계 지점의 주소를 가진 레지스터이다.

메모리 관리자는 사용자가 작업을 요청할 때마다 경계 레지스터의 값을 벗어나는지 검사하고, 만약 경계 레지스터를 벗어나는 작업을 요청하는 프로세스가 있으면 그 프로세스를 종료한다.

절대 주소와 상대 주소의 개념

실제 물리 주소를 가리키는 절대 주소는 메모리 관리자 입장에서 바라본 주소이다.

즉 메모리 주소 레지스터가 사용하는 주소로, 컴퓨터에 꽂힌 램 메모리의 실제 주소를 말한다.

상대 주소는 사용자 프로세스 입장에서 바라본 주소이며, 절대 주소와 관계없이 항상 0번지부터 시작한다.

상대 주소는 사용자 프로세스 입장에서 운영체제가 어디서 끝나는지, 자신의 데이터가 어디에 존재하는지 알 필요 없이 주소 공간이 항상 0번지부터 시작하는데, 이러한 주소 공간을 논리 주소 공간이라고 한다.

구분절대 주소상대 주소
관점메모리 관리자 입장사용자 프로세스 입장
주소 시작물리 주소 0번지부터 시작물리 주소와 관계없이 항상 0번지부터 시작
주소 공간물리 주소(실제 주소) 공간논리 주소 공간

상대 주소를 절대 주소로 변환하는 과정


  1. 사용자 프로세스가 상대 주소 40번지에 있는 데이터를 요청한다.
  2. CPU는 메모리 관리자에게 40번지에 있는 내용을 가져오라고 명령한다.
  3. 메모리 관리자는 상대 주소값에 재배치 레지스터 값을 더하여 절대 주소 400번지로 변환하고 메모리 400번지에 저장된 데이터를 가져온다.

재배치 레지스터는 주소 변환의 기본이 되는 주소값을 가진 레지스터로, 메모리에서 사용자 영역의 시작 주소값이 저장된다.

만약 운영체제 영역이 바뀌어 사용자 영역이 500번지부터 시작한다면 재배치 레지스터에 500을 넣으면 된다.

단일 프로그래밍 환경에서의 메모리 할당

메모리 오버레이

프로그램의 크기가 실제 메모리(물리 메모리)보다 클 때 전체 프로그램을 메모리에 가져오는 대신 적당한 크기로 잘라서 가져오는 기법을 메모리 오버레이라고 한다.

전체 프로그램을 메모리에 올려놓고 실행하기에는 메모리의 크기가 작기 때문에 실행하는 데 필요한 중요한 모듈만 올려놓고 나머지는 필요할 때마다 메모리에 가져와 사용하는 것이다.


그림판이 필요하면 메모리에 그림판을 가져오고, 맞춤법 검사기가 필요하면 그림판을 쫓아내고 그 자리에 맞춤법 검사기를 가져온다.

  • 한정된 메모리에서 메모리보다 큰 프로그램의 실행이 가능하다.
  • 프로그램 전체가 아니라 일부만 메모리에 올라와도 실행이 가능하다.

스왑

메모리 오버레이에서 메모리에 모듈 B를 가져올 때 먼저 메모리에 올라온 모듈 A를 어딘가에 보관해야 한다.

이처럼 메모리가 모자라서 쫓겨난 프로세스는 저장장치의 특별한 공간에 모아두는데 이러한 역할을 스왑 영역이라고 부른다.

그리고 스왑 영역에서 메모리로 데이터를 가져오는 작업은 스왑인, 메모리에서 스왑 영역으로 데이터를 내보내는 작업은 스왑아웃이라고 한다.

하드디스크 같은 저장장치는 저장장치 관리자가 관리하지만, 스왑 영역은 메모리에서 쫓겨났다가 다시 돌아가는 데이터가 머무는 곳이기 때문에 저장장치는 장소만 빌려주고 메모리 관리자가 관리한다.

사용자는 실제 메모리의 크기와 스왑 영역의 크기를 합쳐서 전체 메모리로 인식하고 사용할 수 있다.

예를 들어 실제 메모리의 크기가 1GB, 스왑의 크기가 3GB라면 사용자가 인식하는 메모리는 4GB이다.

이는 실제 메모리가 4GB인 컴퓨터보다 속도가 느리겠지만, 스왑을 사용하면 실제 메모리의 모자란 부분을 보충할 수 있다.

사용자 입장에서는 실제 메모리의 크기에 상관없이 큰 프로그램을 실행할 수 있는 것이다.

This post is licensed under CC BY 4.0 by the author.