[운영체제] Day4 메모리와 페이지 교체(2)

빵코·2024년 4월 8일
post-thumbnail

가상 메모리 관리

고정 분할 방식(페이징)

페이징기법은 메모리 공간을 일정한 크기의 페이지로 나누어 다룬다. => 불연속적 할당

  • 논리주소 공간
    사용지와 프로세스가 참조하는 공간으로 실제 메모리보다 더 큰 공간
    보조기억장치의 크기를 지원받아 크기를 키운 것임.
    논리주소공간의 조각은 페이지라고 부름
  • 물리주소 공간
    실제 메모리의 공간을 뜻함. 물리주소공간의 조각은 프레임이라고 부름.

페이징은 CPU가 논리주소를 통해 메모리에 접근하고 운영체제가 이를 물리주소로 변환하여 실제 메모리에 올리는 방식임. 논리주소공간이 물리주소공간보다 크기때문에 부족한 공간은 스와핑 방법 으로 이뤄지는데, 페이징에서는 이 용어를 '페이지 인' 과 '페이지 아웃'으로 바꾸어 부름.

  • 특징
    페이징 기법은 프로세스에게 불연속적으로 주소를 할당함. 연속적으로 주소를 할당시 외부 단편화가 발생할 수 있지만 불연속적인 방법은 내부 단편화가 발생 할 수도 있음.

    페이지 테이블은 페이지 번호와 프레임 번호를 짝지어 주는것이고 프로세스마다 각자의 페이지 테 이블을 가지고 있어 각 프로세스의 테이블은 메모리에 적제되어 있다.
    따라서 물리공간에 불연속적으로 할당되어 있다고 해도 다음에 실행해야할 프로세스를 적절하게 찾 아갈 수 있다.

페이지 테이블 엔트리

  • 접근비트: 페이지가 메모리로 올라온 후 데이터에 접근성이 있었는지 알려주는 비트
    메모리에 읽기나 실행작업을 했다면 1로 바뀌게 됨.

  • 변경비트: 페이지에 메모리가 올라온 후 데이터의 변경이 있었는지 알려주는 비트
    메모리에 쓰기작업이 있었다면 1로 바뀌게 됨.

  • 유효비트: 페이지가 어디에 있는지 알려주는 비트. 0이라면 페이가 스왑영역, 1이라면 물리메모 리에 있다는 뜻. CPU가 유효비트가 0인 스왑영역에 접근하려 하면 페이지폴트라는
    예외가 발생. 이가 발생하면 프로세스를 바로 실행할 수 없다는 의미.

  • 보호비트: 페이지에 대한 읽기, 쓰기, 실행권한이 어떻게 되는지 나타내는 비트
    100 은 읽기 권한만 있고, 111은 모든 권한이 다 있다는 뜻.

    페이지드 세그멘테이션

    세그멘테이션과 페이징을 혼합한 방식
    세그멘테이션은 가변분할방식이여서 데이터,스텍,코드 영역등 논리적으로 나눠져 있는 영역을 나눠 서 관리 가능, 벗 외부단편화 문제 발생가능
    페이징은 논리적인 영역들을 나눠서 관리는 못함. 벗 메모리 효율이 좋음

    페이지드 세그멘테이션에서는 세그멘테이션 테이블이라는 것을 관리.
    세그먼트 번호, 권한비트, 페이지번호, 크기 등으로 구성되어 있음. 권한비트로 코드영역,스택영역등에 대한 권한에 차이를 부여할 수 있음.

    실습 코드

     foods = ["햄버거", "샐러드", "비스킷"]
    
     print(id(foods))
     # id: 참조자(변수)가 어떤 논리 메모리 주소(논리주소공간)를 참조하고 있는지 반환해주는 함수
     print(hex(id(foods))) #16진수 값
    
     mv = memoryview(b"happy day")
    
     print(mv)
    
     print(mv[0]) #h에 관한 주소
     print(mv[1]) # a
     print(mv[2]) # p
     print(mv[3]) # p
        import psutil
     import os
    
     print("메모리 사용량 조회하기")
    
     memory_dict = dict(psutil.virtual_memory()._asdict()) #시스템메모리 사용량에 대한 통계를 튜플형태로 반환해줌/그것을 딕셔너리로 바꿈
     print(memory_dict)
    
     total = memory_dict['total'] #총량
     available = memory_dict['available'] # 즉시사용가능한양
     percent = memory_dict['percent'] # available제외한 비율(사용중인 비율)
    
     print(f"메모리  총량 : {total}")
     print(f"메모리  즉시 제공 가능량 : {available}")
     print(f"메모리  사용량 : {percent}")
    
     pid = os.getpid()
     current_process = psutil.Process(pid)
    
     kb = current_process.memory_info()[0] / 2 ** 20 # 현재 나의  프로세스가  몇키로바이트  쓰는지 알수 잇음.
     print(f"메모리 사용량 : {kb:.2f} KB")

    <실행결과>

import tracemalloc # 메모리 추적 파이썬 3.4부터 지원됨

tracemalloc.start()

# 메모리 할당이 진행되는 작업 아무거나 해본 것임!
data = [b'%d' % num for num in range(1,10001)]
joined_data = b' '.join(data)

current, peak = tracemalloc.get_traced_memory()
# 현재사용량, 최대사용량
print(f'현재 메모리 사용량: {current / 10 ** 6}MB')
print(f'최대 메모리 사용량: {peak / 10 ** 6}MB')

tracemalloc.stop()

traced = tracemalloc.get_tracemalloc_memory() #프로세스를 추적(트레이스말록)하느라 쓴 메모리
print(traced / 10 ** 6)

<실행결과>

profile
빵먹으면서 코딩하는 개발자를 꿈꾸는 코린이

0개의 댓글