[OS] Main Memory

주기억장치(Main memory)

메인 메모리를 관리하는 것

메모리 역사

  • core memory
  • 진공관 메모리(1950-60)
  • 트랜지스터 메모리
  • 집적회로 메모리 : SRAM, DRAM

메모리 용량

  • 1970 : 8bit PC 64kb
  • 1980 : 16bit IBM PC 640kb > 1mb > 4mb
  • 1990 : 수mb > 수십mb
  • 2000 ~ : 수백mb > 수백gb

메모리는 언제나 부족하다. 왜?

  • 프로그램의 변천

기계어/어셈블리어 작성 -> C언어 작성 -> 자바, 객체지향형 언어 작성 -> 숫자 처리 > 문자 처리 > 멀티미디어 처리 > 빅데이터

  • 메모리 용량 증가 vs 프로그램 크기 증가
  • 어떻게 메모리를 효과적으로 사용할 수 있을까?
    • 메모리 낭비 없애기
    • 가상 메모리 (virtual memory)

메모리 구조

주소 (Address) + 데이터 (data)

  • 프로그램 개발
    • 원천파일 (source file) : 고급 언어, 어셈블리 언어 등의 코드 파일
    • 목적파일 (Object file) : 컴파일 또는 어셈블 결과
    • 실행파일 (Execution file) : 링크 결과
  • 컴파일러, 어셈블러, 링커, 로더

메모리에 하나의 프로그램이 샐행될 땐, code, stack data를 통해 실행된다.

소스코드가 실행되면(컴파일) Object 코드가 만들어진다. 그 후 링크를 하는데, 링크는 다른 Object 파일이나 라이브러리가 될 수 있다. 그렇게 링크를 통해 운영체제 안에 있는 라이브러리와 연결이 되면, 실행파일이 생성된다.

프로그램을 메모리에 올리기

위에서 실행파일을 받은 후, 실행시킬 때, 메모리에 프로그램을 어떤 기준으로 올릴까?

메모리에 어떤 프로그램을 올려서 CPU가 실행시킬 때, 중간에 MMU를 경유하도록 하여 MMU가 CPU가 어떤 프로그램을 실행하는지 감시하도록 작동한다. MMU 안에는 limit register, base register가 있는데, 메모리에 올라온 특정 프로그램의 범위 이상(limit, base 기준) 넘어설 수 없다는 것을 MMU가 기억하도록 한다.

그래서 특정 메모리 위에 있는 프로그램이 갑자기 CPU를 침범하려할 때, 해당 프로그램의 범위가 MMU에 전달되면서 범위를 넘어서는 것을 확인하고, MMU에서 인터럽트 신호를 보내 CPU가 현재 하는 일을 중단하고 OS루틴으로 가서 해당 범위를 침범하는 프로세스를 강제 종료하도록 한다.

다시 돌아와서, 메모리에 프로그램(실행파일)을 올릴때, 어떤 기준으로 올릴까?

  • 메모리 몇 번지에 올릴지?
  • 다중 프로그래밍 환경에서는 어떻게 될지?

MMU 사용

MMU에는 Relocation register가 있다. 이 레지스터는 OS가 특정 프로그램의 실행파일을 만들 때, 적재되는 메모리의 주소를 정해놨다고하자. 그렇게 해당 프로그램이 메모리에 올라갈 때, 정해진 주소로 들어가지 않으면 제대로 작동하지 않는다. 이 때, 메모리 주소를 재배치하는 아이가 Relocation register라고 한다. 실행파일이 메모리에 올라가는 것을 적재되었다고 표현한다.

다시 정리하면, 실행파일에서 정해진 메모리 주소를 통해 CPU가 해당 실행파일을 들고오려하면, 중간에 MMU가 Relocation register를 사용하여 CPU가 가져오려는 메모리 주소 위치를 알맞게 현재 메모리에 해당 실행파일이 있는 번호를 가져와서 CPU에게 해당 메모리 주소 위치에 있는 것처럼 중간에서 전달하는 것이다… (머리로는 이해되는데 말로 풀기 어렵다)

다시 요약하면, 실행파일이 현재 메모리 어디에 적재되어있는지 상관없이, CPU가 몇번째에 있다 생각하고 실행하면, MMU가 해당 실행파일의 위치에 맞게 가져오는 것이다. (address translation)

  • 논리주소(logical address)
  • 물리주소(physical address)

CPU가 아는 주소가 따로 있고(logical address 논리주소), 메모리가 가진 주소가 따로 있다.(physical address 물리주소)

즉, 프로그램이 메인메모리에서 어디에 있는지는 아무 문제가 되지 않는다. MMU가 알아서 해줌!!

메모리 낭비 방지

동적 적재 (Dynamic Loading)

만들어진 실행파일을 메모리에 올리는 것을 Load한다, 또는 적재한다라고 한다.

실행파일이 실행되면, 일단 open되고, 만약 실행파일이 존재하지 않으면 실행되는 코드가 존재된다. 하지만 정상적인 경우 open이 될 것이다. 이런 경우 대부분의 실행파일은 잘 open될 것이기 때문에, 오류처리루틴은 낭비가 되는 코드일 수 있다. 즉, 모든 루틴이 다 사용되는 것이 아니다.

그래서 해당 프로그램 실행에 반드시 필요한 루틴/데이터만 적재하도록 한다. 만약 정말로 오류가 일어나면, 그 때, 오류처리루틴을 메모리에 적재하여 사용한다. 이런 경우에 따라 데이터 및 루틴을 적재하도록 하는 것이 동적 적재이다.

동적 연결 (Dynamic Linking)

프로그램을 메인메모리에 올릴 때, 여러 프로그램 실행파일 내부 코드 중 공통된 부분이 존재한다. 이는 메모리 내부에서 낭비가 되게 때문에, 공통 라이브러리 루틴을 오직 하나만 올리도록 한다. 즉, 실행파일 만들기 직전에 링크를 하지 않고(원래는 이때 한다! 이것을 정적 연결(static linking) 일단 메모리에 올리고, 해당 메모리에 다른 어플리케이션 실행시 이 루틴과 연결하여 사용하도록 하는 것이다.

요약하면, 중복되는 라이브러리 및 데이터를 하나만 메모리에 적재하고, 공통된 부분이 실행될 때마다 다른 어플리케이션과 연결(link)하여 공통된 부분을 재사용하도록 하는 것이다.

Swapping

메모리에 적재되어있지만, 사용되지 않고 있는 프로세스 이미지를 말한다. 작동하다가 중간에 사용되지 않는 프로세스의 경우 OS가 메모리에 올려있는, 사용되지 않는 프로세스는 치워버리는 것이다.

현재 실행되고 있는 프로세스 이미지가 잠시 사용되고 있지 않으면, OS가 하드웨어의 특정 공간에다가 잠시 해당 프로세스 이미지를 넣어놓아 메모리의 낭비를 막도록 한다. 이런 공간은 Backing Store라고 한다. 후면기억장치, Swap Device라고도 하는 듯. Backing Store의 크기는 메인메모리의 크기와 비슷하다고 보면 된다.

다시 해당 프로그램이 실행되는 경우, OS가 Backing Store에서 다시 프로세스를 가져와서 메모리의 빈 곳에다가 집어넣는다. 위치가 바껴도 MMU의 Relocation register 덕에 신경쓸 필요는 없다는 것! 그리고 이런 일이 일어나게되면, 속도가 좀 느려지게 된다. 하드웨어에서 왓다갓다하는 것이 부담이 되서 그런듯, 하지만 이렇게 하는 것이 메모리 낭비를 막기에 효율적이기 때문에 사용된다.