콘텐츠로 이동

메모리

메모리

메모리 계층

  • 레지스터 : CPU 안의 작은 메모리
  • 캐시 : L1, L2 캐시
  • 주기억장치 : RAM
  • 보조기억장치 : HDD, SSD

현구막의 리눅스 메모리 관리

  • 참고: https://www.youtube.com/watch?v=qxmdX449z1U
  • 메모리가 관리되는 방법
    • 코드 -(컴파일러)-> 숫자
    • 컴파일러가 변화시킨 숫자 주소를 "논리 주소"라고 부름
    • 주소 변환
      • 모두 같은 주소를 가진 "가상 주소"를 가짐 (논리 주소가 곧 가상 주소)
      • Hello World 프로그램 => 00~19 메모리 주소 가짐
      • Holy Moly 프로그램 => 00~19 메모리 주소 가짐
    • 그러면 논리 주소 겹치자나?
      • 각 프로그램에 고유한 번호를 앞에 붙여 => 이게 "물리 주소"
    • 아니, 그러면 처음부터 물리주소로 변환하지 그랬냐?
      • CPU는 논리 주소만 읽거든
      • CPU 입장에선 현재 활동중인 프로세스 내부의 주소만 알면 되거든
  • MMU
    • Base Register, Limit Register, 산술 연산기
    • CPU 사용중인 프로세스가 요청하는 논리주소에 Base Register 값 더해서 물리 주소로 변환
    • 이때 변환된 물리 주소가 Limit Register 안짝에 있는지 검증
  • 메모리 할당
    • 프로세스들을 그러면 하나씩 물리 메모리에 올려봅시다
    • 이렇게 하나하나 꽉 채웠다가 하나 끝났고, 새로운 프로세스 메모리에 올릴라니까 음... 공간이 부족하네
    • 그러면 불필요한 하나의 프로세스를 하드디스크로 뺍시다
      • 오 느려, 뭘 빼야할지도 모르겠어
    • 구멍 계속 생겨...
  • Paging
    • 메모리 공간을 일정하게 잘라두고, 프로그램을 잘라서 조금씩 올리자!
    • 물리 메모리를 일정하게 자르자!
      • 이걸 Frame이라고 부르기로 했어요
    • 프로그램을 일정하게 자르자!
      • 이걸 Page라고 부르기로 했어요
    • 당장 프로그램이 동작하는데 필요한 Page만 Frame에 올려서 사용하기로 하고, 나머진 스왑 공간에 쟁여두기로 했어요
    • 그 결과...
      • 프로그램 별로 Page 여기저기 흩어져 버림.
      • MMU 연산도 빡세짐
    • 따라서...
      • 논리 <-> 물리 주소 변환을 위한 페이지 테이블을 생성
  • Paging Table
    • 프로세스마다 페이지 테이블이 필요해졌어
    • 이는 메모리에 저장됨
    • 프로세스마다 페이지 테이블 메모리에 놓으면 너무 용량 많자나
      • 그래서 공통되어 공유할 수 있는 페이지는 물리 메모리에 박아두기로 했어
    • 잠깐 그러면 CPU 입장에서 정보 요청하려면, 메모리 총 2번 왔다갔다 해야해?
      1. 페이지 테이블 접근해서 페이지 정보 가져오고
      2. 페이지 접근해서 실제 정보 가져오고
    • 그러면 안되니까, TLB를 통해 페이지 테이블 캐시 만들어두자고!
  • Paging with TLB
    • TLB에 주소 있으면 바로 가져올 수 있겠지?
  • 정리
    • 현대 메모리는 Paging을 베이스로한 기법을 채택
    • 하드디스크를 Swap area로 활용
    • MMU, TLB 같은 하드웨어 지원을 통해 Page Table 확인해 메모리 참조
  • 가상 메모리로 어플리케이션 프로세스 속이기
    • CPU에서 처리되고 있는 프로세스는 자기가 거대한 메모리에 몽땅 올라와있다고 생각함
      • 실제로는 실제 처리되고 있는 부분의 페이지만 메모리에,
      • 나머지는 스왑공간에 쟁여두고 있음
    • 물리메모리 공간 + 스왑공간 = 가상 메모리
  • Page Fault
    1. CPU가 프로세스 작업중
    2. CPU: 메모리 주소 좀~
    3. TLB: 어라? 메모리 저장된거 없는디?
    4. MMU: 어이 프로세스. 잠들어라
    5. OS 등판. CPU 점유
    6. OS: 하드디스크 스왑공간에서 메모리에 페이지 가져오고, TLB도 업데이트 해드렸습니다~
    7. CPU: OS 잠들어라. - Page Fault 발생 == CPU Context Switching 이런거 다 일어나니까 성능 저하
  • Page Replacement
    • 메모리 꽉차면 내쫓을 페이지 선택 by OS
    • 이상적인건 LRU
      • 하지만 OS는 페이지 폴트나서 메모리에 올려준 정보만 있어
      • 그게 CPU님께서 얼마나 최근에 접근하셨는지에 대한 정보는 없어
    • Clock Algorithm
      • 메모리에 올라와 있는 모든 page가 reference bit = 0
      • cpu를 점유중인 프로세스가 호출하면 reference bit = 1
      • 내쫓을 타이밍에 페이지 하나씩 보면서 reference bit이 0이면 내쫓기
        • else reference_bit--;
  • Thrashing
    • 다양한 프로그램들이 메모리에 올라오고, 유효공간 줄어들고 CPU 최대한 많이 쓰고
    • 그러다가 CPU 사용량 똑 떨어져
      • 메모리에 프로세스 많아질수록 프로세스 당 쓸 수 있는 물리 메모리 프레임 줄어들고
      • 그러다보니 프로세스 하나가 실행되던 중 page fault에 걸려서 replacement 진행
      • 딴 프로세스가 CPU 바통 이어받지만 똑같이 page fault
    • 모든 페이지가 교체되기 바쁘고 CPU는 놀아
      • CPU 노니까 프로세스 더 올려!
  • Thrashing 해소 - Working Set
    • 대부분 프로세스가 일정한 페이지만 집중적으로 쓰는구나!
    • 특정 시간 동안에 프로세스의 참조되는 페이지 갯수를 파악해서 이게 제대로 다 올라갈 frame이 확보된 이후에 page 올림
    • "프로세스" 별로 동작
  • Thrashing 해소 - PFF
    • page fault rate 상한 하한 둠
      • 상한 넘으면 지급 프레임 갯수 줄이고
      • 하한을 넘으면 지급 프레임 갯수 늘리고
    • "프로세스" 단위로 동작!