ComputerScience

메모리

Albosa2lol 2023. 11. 8. 02:07

1 메모리 계층

메모리 계층은 레지스터, 캐시, 메모리, 저장장치로 구성되어 있다.


- 레지스터 : CPU 안에 있는 작은 메모리, 휘발성, 속도 가장 빠름, 기억 용량이 가장 적다.
- 캐시 : L1, L2 캐시를 지칭한다. 휘발성, 속도 빠름, 기억 용량이 적다. 참고로 L3 캐시도 있다.
- 주기억장치 : RAM을 가리킵니다. 휘발성, 속도 보통, 기억 용량 보통
- 보조기억장치 : HDD, SSD를 일컬으며 비휘발성, 속도 낮음, 기억 용량이 많다.

램은 하드디스크로부터 일정량의 데이터를 복사해서 임시 저장하고 이를 필요 시마다 CPU에 빠르게 전달하는 역할을 한다.

🟡 캐시

캐시(cache)는 데이터를 미리 복사해 놓는 임시 저장소이자 빠른 장치와 느린 장치에서 속도 차이에 따른 병목 현상을 줄이기 위한 메모리를 말한다.
이를 통해 데이터를 접근하는 시간이 오래 걸리는 경우를 해결하고 무언가를 다시 계산하는 시간을 절약할 수 있다.

실제 메모리와 CPU 사이의 속도 차이가 크므로 중간에 레지스터 계층을 두어 속도 차이를 해결한다. 이를 캐싱 계층이라고 하는데 예를 들어 캐시 메모리와 보조 기억 장치 사이에 있는 주기억장치를 캐싱 계층이라고 한다.

🟢 지역성의 원리?

그렇다면 캐시 계층을 두는 것 말고 캐시를 직접 설정할 때는 어떻게 해야 할까? 자주 사용하는 데이터 기반으로 설정해야 한다.

자주 사용하는 데이터의 근거 : 지역성

  • 시간 지역성 : 최근 사용한 데이터에 다시 접근하려는 특성
  • 공간 지역성 : 최근 접근한 데이터를 이루고 있는 공간이나 그 가까운 공간에 접근하는 특성

🟡 캐시히트와 캐시미스

캐시에서 원하는 데이터를 찾았다면 캐시히드라고 하며, 해당 데이터가 캐시에 없다면 주 메모리로 가서 데이터를 찾아오는 것을 캐시미스라고 한다.

  • 캐시히트는 위치가 가깝고 CPU 내부 버스를 기반으로 작동하기 때문에 빠르다.
  • 캐시미스가 발생되면 메모리에서 가져오게 되는데, 시스템 버스 기반으로 작동하기 때문에 느리다.

캐시매핑

  • 캐시가 히트되기 위해 매핑하는 방법.

🌟 웹 브라우저의 캐시

  • 쿠키 : 만료기한이 있는 키-값 저장소. same site 옵션을 strict로 설정하지 않았을 경우 다른 도메인에서 요청했을 때 자동 전송되며, 4KB까지 데이터를 저장할 수 있고 만료 기한을 정할 수 있다. 쿠키를 설정할 때는 domain.cookie로 쿠키를 볼 수 없게 httponly 옵션을 거는 것이 중요하며, 클라이언트 또는 서버에서 만료기한을 정할 수 있는데 보통 서버에서 만료기한을 정한다.
  • 로컬 스토리지 : 만료기한이 없는 키-값 저장소. 10MB까지 저장 가능하며, 웹 브라우저를 닫아도 유지되고 도메인 단위로 저장, 생성된다. HTML5를 지원하지 않는 웹 브라우저에서는 사용 불가하며 클라이언트에서만 수정 가능하다.
  • 세션 스토리지 : 만료기한이 없는 키-값 저장소. 탭 단위로 세션 스토리지를 생성하며, 탭을 닫을 때 해당 데이터가 삭제된다. 5MB까지 저장 가능. HTML5를 지원하지 않는 웹 브라우저에서는 사용 불가하며 클라이언트에서만 수정 가능하다.

2 메모리 관리

운영체제의 대표적인 할 일 중 하나는 메모리 관리이다. 컴퓨터 내의 한정된 메모리를 극한으로 활용하는 것이 핵심이다.

가상 메모리(virtual memory)

메모리 관리 기법의 하나로 컴퓨터가 실제로 이용 가능한 메모리 자원을 추상화하여 이를 사용하는 사용자들에게 매우 큰 메모리로 보이게 만드는 것

가상 주소는 메모리관리장치(MMU)에 의해 실제 주소로 변환되며, 이 덕분에 사용자는 실제 주소를 의식할 필요 없이 프로그램을 구축할 수 있게 된다.

스와핑

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

페이지 폴트(page fault)

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

스레싱(thrashing)

메모리의 페이지 폴트율이 높은 것을 의미하며, 이는 컴퓨터의 심각한 성능 저하를 초래한다.

스레싱은 메모리에 너무 많은 프로세스가 동시에 올라가게 되면 스와핑이 많이 일어나 발생하는 것이다.

페이지 폴트가 일어나면 CPU 이용률이 낮아져 운영체제는 CPU가 한가하다고 판단하여 가용성을 높이기 위해 더 많은 프로세스를 메모리에 올리게 된다. 이와 같은 악순환이 반복되며 스레싱이 일어나게 되는 것이다.

어떻게 해결할까?

  1. 메모리를 늘린다.
  2. HDD를 사용한다면 SSD로 바꾼다.
  3. 운영체제에서는 작업 세트와 PFF로 해결 가능하다.

작업 세트(working set)

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

PFF

: 페이지 폴드 빈도를 조절하는 방법으로 상한선과 하한선을 만드는 방법. 상한선에 도달하면 프레임을 늘리고 하한선에 도달하면 프레임을 줄이는 것이다.

메모리 할당

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

페이지 교체 알고리즘

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

FIFO(First In First Out)

: 가장 먼저 온 페이지를 교체 영역에 가장 먼저 놓는 방법

LRU(Least Recently Used)

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

LFU(Least Frequently Used)

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


3 프로세스와 스레드

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

3.1 프로세스와 컴파일 과정

  • 컴파일 : 컴파일러가 컴퓨터가 이해할 수 있는 기계어로 번역하여 실행할 수 있는 파일을 만드는 것
  • 컴파일 과정

전처리

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

컴파일러

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

어셈블러

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

링커

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

정적 라이브러리와 동적 라이브러리

  • 정적 라이브러리는 프로그램 빌드 시 라이브러리가 제공하는 모든 코드를 실행 파일에 넣는 방식으로 라이브러리를 쓰는 방법이다. 시스템 환경 등 외부 의존도가 낮은 장점이 있지만 코드 중복 등 메모리 효율성이 떨어지는 단점이 있다.
  • 동적 라이브러리는 프로그램 실행 시 필요할 때만 DLL이라는 함수 정보를 통해 참조하여 라이브러리를 쓰는 방법이다. 메모리 효율성에서의 장점을 지니지만 외부 의존도가 높아진다는 단점이 있다.

3.2 프로세스의 메모리 구조

: 스택은 위 주소부터 할당되고 힙은 아래 주소부터 할당된다.

스택과 힙

스택과 힙은 동적 할당이 되며, 동적 할당은 런타임 단계에서 메모리를 할당받는 것을 말한다. 스택은 지역 변수, 매개변수, 실행되는 함수에 의해 늘어나거나 줄어드는 메모리 영역이다. 함수가 호출될 때마다 호출될 때의 환경 등 특정 정보가 스택에 계속해서 저장된다.

데이터 영역과 코드 영역

정적 할당되는 영역이다. 정적 할당은 컴파일 단계에서 메모리를 할당하는 것을 말한다.

3.3.3 PCB

PCB(Process Control Block)는 운영체제에서 프로세스에 대한 메타데이터를 저장한 '데이터'를 말한다. 프로세스 제어 블록이라고도 한다. 프로세스가 생성되면 운영체제는 해당 PCB를 생성한다.
프로그램이 실행되면 프로세스가 생성되고 프로세스 주소 값들에 앞서 설명한 스택, 힙 등의 구조를 기반으로 메모리가 할당된다. 그리고 이 프로세스의 메타데이터들이 PCB에 저장되어 관리된다. 이는 프로세스의 중요한 정보를 포함하고 있기 때문에 일반 사용자가 접근하지 못하도록 커널 스택의 가장 앞부분에서 관리한다.

PCB의 구조

: 프로세스의 스케줄링 상태, 프로세스 ID 등의 다음과 같은 정보로 이루어져 있다.

  • 프로세스 스케줄링 상태: '준비', '일시중단' 등 프로세스가 CPU에 대한 소유권을 얻은 이후의 상태
  • 프로세스 ID: 해당 프로세스의 자식 프로세스 ID
  • 프로세스 권한: 컴퓨터 자원 또는 I/O 디바이스에 대한 권한 정보
  • 프로그램 카운터: 프로세스에서 실행해야 할 다음 명령어의 주소에 대한 포인터
  • CPU 레지스터: 프로세스를 실행하기 위해 저장해야 할 레지스터에 대한 정보
  • CPU 스케줄링 정보: CPU 스케줄러에 의해 중단된 시간 등에 대한 정보
  • 계정 정보: 프로세스 실행에 사용된 CPU 사용량, 실행한 유저의 정보
  • I/O 상태 정보: 프로세스에 할당된 I/O 디바이스 목록