4-9 메모리

do·2022년 6월 2일
1

API

목록 보기
36/42

리눅스 가상 메모리

리눅스의 각 프로세스는 4GB를 차지한다.
프로세스를 실행하기 위해서는 코드가 반드시 메모리에 있어야 하는데,
어떻게 하면 한정된 메모리에서 여러 프로세스를 실행시킬 수 있도록 메모리 구조를 가져갈 수 있을까?
이때 활용하는 것이 가상 메모리이다.
가상 메모리를 통해 프로세스간 공간을 분리하면, 프로세스 이슈가 전체 시스템에 영향을 주지 않을 수 있다.
가상 메모리를 통해 메모리 용량 부족프로세스 메모리 영역 간 침범 이슈를 해결할 수 있다.

가상 메모리의 기본 아이디어는, 프로세스는 가상 주소를 사용하고, 데이터를 사용(읽기/쓰기)할 때 물리 주소로 변환해주는 것이다.

  • 가상 주소(virtual address) 프로세스가 참조하는 주소
  • 물리 주소(physical address) 실제 메모리 주소

그리고 특정 가상 주소가 어느 물리 주소에 매핑 되어있는지 알 수 있어야 한다. 이때 필요한 것이 MMU이다.

  • MMU(Memory Management Unit) CPU에 코드 실행시, 가상 주소 메모리에 접근할 때, 해당 주소를 물리 주소값으로 변환해주는 하드웨어 장치
    즉, CPU는 가상 메모리를 다루고, 가상 메모리의 가상 주소에 접근시 MMU 하드웨어를 통해 물리 주소로 변환되어 물리 메모리에 접근한다.

프로세스 메모리 영역

  • Text(Code) 영역
    • 실행할 프로그램의 코드
    • CPU는 이 영역에서 명령어를 하나씩 가져와 처리함
  • Data 영역
    • 전역변수(global), 정적변수(static)
    • 프로그램이 시작될 때 할당되어, 프로그램이 종료하면 소멸된다.
    • 초기화된 데이터
    • 함수 내부에 선언된 정적변수(static)는 프로그램이 실행될 때 공간만 할당되고, 그 함수가 실행될 때 초기화.
  • BSS (Block Started by Symbol) 영역
    • 초기화 되지 않은 데이터(전역변수)

Data 영역과 BSS 영역을 구분하는 이유

  • 초기화된 전역변수는 Data 영역에 저장되어 비휘발성 메모리인 ROM에 저장되는데, 이 부분은 비용이 많이 들어 RAM에 저장될 것과 ROM에 저장될 것을 구분하기 위해, Data 영역과 BSS 영역을 나누어 사용합니다.
  • Heap
    • 가상 메모리 영역을 관리함
    • 프로그램 동작 시(런타임)에 크기가 결정된다.
    • 메모리 주소값에 의해서만 참조되고 사용되는 영역
  • Stack
    • 프로그램이 자동으로 사용하는 임시 메모리 영역
    • 지역변수(local), 매개변수, 리턴값 등 잠시 사용되었다가 사라지는 데이터
    • 스택 사이즈는 각 프로세스마다 할당되지만 프로세스가 메모리에 로드될 때 스택 사이즈가 고정되어 있어, 런타임 시에 스택 사이즈를 바꿀 수는 없다.
    • 컴파일 타임에 크기 결정

API

1. malloc()

함수 원형. void *malloc(size_t size)
기능. 메모리 동적할당
헤더. <stdlib.h>
매개변수. size_t size 메모리의 크기
리턴값.
성공 할당한 메모리의 첫번째 주소
실패 NULL

int *arr;
arr = (int *)malloc(sizeof(int) * 5); //배열 5개. 총 20바이트로 할당함

2. calloc()

함수 원형. void *calloc(size_t count, size_t size)
기능. malloc과 다른 점은, 할당된 공간의 값을 모두 0으로 초기화 시켜준다.
헤더. <stdlib.h>
매개변수1. size_t count 메모리의 갯수
매개변수2. size_t size 메모리의 크기
리턴값.
성공 할당한 메모리의 첫번째 주소
실패 NULL

int *arr;
arr = (int *)calloc(5, sizeof(int));

3. realloc()

함수 원형. void *realloc(void *ptr, size_t newsize)
기능. 이미 할당된 메모리의 크기를 변경함
헤더. <stdlib.h>
매개변수1. void *ptr 이미 할당된 포인터 변수
매개변수2. size_t newsize 바꾸고 싶은 메모리의 크기
리턴값.

realloc(arr, sizeof(int) * 10); //arr의 메모리를 40바이트로 재할당함

4. free()

함수 원형. void free(void *ptr)
기능. 메모리 해제
메모리를 동적할당하면 힙에 공간이 생기는데, 이 공간은 프로그램이 종료될 때까지 존재한다.
따라서 메모리를 할당만 하고 해제를 하지 않으면 사용하지는 않는데 메모리 사용량만 계속 증가해서 메모리 누수가 발생한다.
(회수하지 않으면 프로그램이 실행되는 동안 그 공간은 계속해서 살아있고 이는 메모리의 낭비를 초래하여 성능 부하를 일으킬 수 있음. 따라서 꼭 free를 통해 회수해야함)
헤더. <stdlib.h>
매개변수. void *ptr 해제하고자 하는 메모리의 포인터

0개의 댓글