CS - 운영체제(8) 메모리 관리(1)

김영현·2023년 7월 10일
0

CS

목록 보기
10/32
post-thumbnail

가상메모리와 물리 메모리

프로그램이 컴파일 되면, 주소공간을 할당받는다. 이는 실제 메모리에 올라간것이 아니다.
저번에 메모리에서 설명했듯, 물리적으로 바로 올라가는것이 아닌 가상 메모리에 한번 탑재된다.
이때 가지는 주소를 Logical address(virtual address)라고 한다.

이후 메모리에 탑재되면 그제서야 Physical address를 부여받는다.

CPU는 물리적 메모리가 아닌, Logical address를 바라본다!

주소 바인딩 방법 3개.

OS에서 메모리 주소를 바인딩하는 방법엔 3가지가 있다.

  • Compilte time : 컴파일 할때
  • Load time : 물리적인 메모리에 프로그램이 올라갈 때
  • Execution time(run time) : 위와 같지만, 실행 도중에 물리적인 주소가 바뀔 수 있음

요즘은 대부분 런타임 바인딩을 사용한다!

MMU(Memory-Management Unit)

런타임 바인딩이 되려면, 하드웨어적 지원이 필요하다.


Dynamic-Memory-Management(동적 메모리 관리)

동적으로 메모리를 관리하는 기법들을 소개하겠다.
다음 목차에 나올 Dynamic-Memory-Allocation을 포괄하는 개념같다.

Dynamic Loading

요즘은 운영체제가 dynamic loading을 지원한다.

Overlays

언뜻 보면 dynamic loading과 비슷한 개념이다.
하지만 메모리의 크기가 아주 작을때 유용하다. 또한 운영체제나 라이브러리의 지원이 없기때문에 코딩을 통해 메모리를 관리해야한다.

Swapping

preempitve와 비슷하다. 프로세스를 일시적으로 보조기억장치로 쫓아낸다.
swapping은 저~번 시간에 설명한 중기 스케줄러에서 쓰이는 swap개념과 일치한다.
swapping을 효율적으로 사용하려면, run time바인딩이 좋다.
다른 두가지 바인딩은 쫓아냈다 불러올때, 같은 주소에 올려야 함.

https://velog.io/@loevray/CS-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4#%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%8A%A4%EC%BC%80%EC%A5%B4%EB%A7%81

Dynamic Linking

  • Linking : 여러 개의 코드와 데이터를 모아서 연결하여 메모리에 로드될 수 있고 실행될 수 있는 한 개의 파일로 만드는 작업.
    웹 개발할때 Webpack으로 묶는 것과 유사하군!


Dynamic-Memory-Relocation(동적 메모리 할당)

메모리는 보통 두영역으로 나뉘어서 사용.
OS공간과 사용자 공간. OS공간은 낮은주소, 사용자공간은 높은주소를 쓴다.

프로세스는 메모리에 이렇게 적재된다.

  1. relocation register가 시작값을 가진다.
  2. limit register가 프로그램의 최대 메모리 양을 갖는다.
  3. 위의 둘을 더한값이, 프로세스가 가질 수 있는 메모리 주소의 최댓값.
  4. 가상메모리에서 프로세스 할당 기법을 통해 물리적 메모리에 올린다!

실제론, 이렇게 관리되진 않는다. 보통 잘개 쪼개서 올라감.

사용자 영역에서 프로세스영역을 할당하는 법은 두가지로 나뉜다.
1. Contiguous allocation (연속, 인접 할당) : 프로세스를 연속된 메모리 공간에 적재하는것이다.
2. Noncontiguous allocation (불연속, 불인접 할당) : 프로세스를 연속된 메모리 공간이 아닌, 여러 영역에 분산해서 올리는 기법이다.

contiguous allocation

연속적으로 탑재하니까, 메모리에 적재된 프로세스가 빠져나가면 Hole이 생긴다.
운영체제는 할당공간과 이 Hole을 기억해야한다.
=> 다음 프로세스의 크기가 Hole에 맞으면 넣어야함

Hole엔 두가지종류의 Fragmentation(단편화)가 존재한다.

  1. 외부 단편화 : 할당-해제가 반복되어 작은 메모리가 중간중간 생기는 것
  2. 내부 단편화 : 프로세스 크기보다 큰 메모리가 할당되어 빈 공간이 남는것.

Dynamic-storage allocation problem

연속 할당기법의 가변 분할 기법에서 어떤 hole에 프로세스가 탑재되어야 하는지를 찾는 알고리즘이다.

compaction(연속할당 기법 - 외부단편화 문제 해결)

연속 할당 기법에서 외부 단편화 문제를 해결하는 방법 중 하나다.
사용중인 메모리 영역을 한군데로 몰아, hole을 작게, 작게 만드는 것이다!
하지만 비용이 많이 든다. 또한, 프로세스의 주소가 런타임에 동적재배치(런타임 바인딩)가 가능해야한다.


Noncontiguous allocation

프로세스를 메모리에 불연속 할당하는 기법엔 세가지가 있다.
1. Paging : 프로세스를 구성하는 주소공간을 페이지(잘게)쪼개 적재함. 같은 크기를 가짐.
2. Segment : 페이징처럼 쪼개지만, 크기가 각각 다르다.
3. Paged Segmentaion : ?

Paging

  • 가상 메모리도 동일한 사이즈의 Page로 나눈다.

페이징 기법은 잘개 쪼개는것. 잘개 쪼겐 프로세스의 위치를 알기 위해선, 탑재하기 전에 페이지와 실제 주소를 매핑해야한다.

  • Paging table : 물리적 주소와 매핑되어있음.

아래는 조금 더 자세히 설명한 페이징 기법의 실행 순서다.

  1. CPU에서 페이지를 찾는다.
  2. page table에서 그 페이지와 매핑된 번호를 찾음.
  3. 2번에서 받아온 번호를 기반으로 물리적 메모리에서 페이지를 찾는다.

페이징 기법에서 사용하는 page table은 결국 각 프로세스 별로 가져야한다.
MMU에서처럼 레지스터에 적재할 순 없다. 용량이 너무 크기 때문이다.
따라서 page table메모리에 적재한다.
=> 한번 접근하려면, 두번의 메모리 접근을 거쳐야함
MMU에서 사용한 두가지의 레지스터를, page table주소와 크기를 가리키는 레지스터로 바꿔서 사용한다.
=> 두번 접근해야하니까, 속도향상을 위해 하드웨어 캐시를 사용한다
(빈번히 참조되는 page table을 캐시해놓음)
그걸 바로 TLB라고 한다.

Two-level-paging table

현대의 컴퓨터에서 돌아가는 프로세스(프로그램)은 메모리 사용 용량이 큼.
따라서 page table을 메모리에 넣게되면, 공간 낭비가 심해진다.
=> page tablepage화 시켜서 공간 낭비를 최소화 함.

two-level page table은 아래와 같은 방식으로 작동한다.
1. 바깥 page table주소를 찾는다.
2. 거기서 내부 page table주소를 찾는다.
3. 물리적 주소를 찾는다.

어떻게 보면 외부 테이블 => 내부 테이블 과정만 하나 추가되서 간단하다.


잠깐, 용어를 잘 모르겠다.

반효경님의 운영체제 강의를 듣다보니 의문이 생겼다. 명확히 설명 안해주고 넘어가신 부분이라...나 혼자 찾아봄

  1. 물리적 메모리를 나눈 단위가 F(frame). 가상메모리를 나눈 단계가(page)
    그래, 생각해보면 물리적 메모리를 나누는게 아니라, 가상메모리를 나눠서 탑재하는거다.

  2. page offset이란?
    => page offset을 설명하려면, page entry를 자세히 짚고 넘어가야 한다.
    보통 하나의 page4KB의 크기를 가진다. 즉, 이는 한덩어리.
    4Kb2의 12승. 따라서 page는 메모리에서 2의 12승만큼의 주소를 가진다.
    => 결국, 하나의 page 내부 주소를 구분지으려면 2의 12승만큼의(12bit)offset이 필요함.

  3. page entry란?
    => page 내부에 있는 최소 단위.

  4. page table은 어디있지?
    => 메모리 안에 있다. 그리고 MMU안에 page table 주소를 가리키는 레지스터가 존재(포인터).

  5. 메모리 한칸은 1byte이다, 32bit면 메모리 하나당 32bit === 4byte.

문제를 풀어보자

  1. 페이지 크기가 4kb고, 메모리 크기가 256kb인 시스템이 있다. 최대 페이지 개수는?
    => 4kb * 64 = 256kb. 따라서 64개

  2. 이 페이지의 offset 크기는?
    => 4kb는 약 2^12. 따라서 12비트 or 메모리 크기 2^18에서 page의 최대 갯수인 2^6을 나눠주면 된다

  3. 메모리 주소를 표현하는데 필요한 크기
    => 256Kb는 약 2^18 byte이다. 따라서 18비트만 있으면, 256kb메모리의 모든 주소를 표현할 수 있다.


이번 시간에는 physical memory와 virtual memory, 그리고 메모리 관리에 대해 배웠다.

  1. 바로 물리적 메모리에 적재되는것이 아니라, 가상메모리에 들렀다가 적재된다.
  2. 물리적 메모리에 적재되는 방식에는 3가지가 있다.
    2-1. 컴파일 도중
    2-2. 실행 도중.
    2-3. 실행 도중 + 도중에 주소 변경가능(런타임)
  3. 런타임 바인딩이 되려면 하드웨어적 지원 필요. 그게 즉 Memory Management-unit
    3-1. 두개의 레지스터가 시작 주소와 한계주소를 저장함.(시작 위치 + 프로세스가 사용하는 메모리 총량)이렇게 더해서 주소를 바인딩해준다.
  4. 동적 메모리 관리에는 크게 4가지가 있다.
    4-1. dynamic-load. 프로세스 전부 탑재x. 루틴을 불러올때마다 메모리적재.
    4-2. overlays. 위와 동일하지만, 메모리 용량이 아주 작던 시절에 사용.
    4-3. swap. 중기스케줄러에서 사용하던것(우선 순위 큐). 우선순위가 낮은애들은 보조기억장치로 내쫓음
    4-4. dynamic linking. 링킹을 실행시간까지 늦춤.
    => 프로세스 간 겹치는 라이브러리 많으면 유용. 라이브러리를 실행시간에 링킹해서 메모리 적재. 겹치는 라이브러리 사용시, 메모리에서 찾고 없으면 그제서야 링킹.
  5. 동적 메모리 할당은 크게 2가지로 나뉨. 연속 할당과 불연속 할당.
    5-1. 연속할당(고정 분할) : 물리적 메모리를 영구적으로 나눔. 융통성x. 내부 단편화(할당 메모리가 프로세스보다 큼)발생. 외부 단편화도 발생 가능.
    5-2. 연속할당(가변 분할) : 넣을때 가변적으로 메모리 크기를 조정함. 외부단편화 발생(할당-해제 하면서 프로세스 사이사이 메모리 낭비 발생).
    => 해결하는 알고리즘 3가지.
    first fit : size가 n 이상인것 중 최초로 만족하는 단편화에 삽입.(나름 빠름)
    best fit : n이상인 것중 가장 작은것(시간 오래걸림)
    worst fit : 가장 큰 단편화에 삽입(너무 별로인데?)
    당연히 worst fit이 가장 안좋음
    5-3. 불연속 할당(paging) : 프로세스를 가상의 단위인 page로 잘게 쪼갬. page table을 만들어서, 실제 메모리에 적재된 page들과 1:1 매핑함. page의 최소 단위는 entry

profile
모르는 것을 모른다고 하기

0개의 댓글