00. 동적 메모리 할당기
- 동적 메모리 할당기는 힙(heap)이라고 하는 프로세스의 가상의 메모리 영역을 관리한다.
- 힙이 미초기화 된 데이터 영역 직후에 시작해서 위쪽으로(높은 주소 방향으로) 커지는 메모리 영역
- 커널은 힙의 꼭대기를 가리키는 변수 brk(break)를 사용한다.
- 할당기는 힙을 다양한 크기의 블록들의 집합으로 관리한다.
(1) 명시적인 할당기
- 응용이 명시적으로 할당된 블록을 반환해 줄 것을 요구한다.
- C 표준 라이브러리는 malloc 패키지라고 하는 명시적 할당기를 제공한다.
- malloc 함수를 호출하여 블록을 할당, free 함수를 호출해서 블록을 반환
(2) 묵시적 할당기
- 블록이 더 이상 프로그램에 의해 사용되지 않을 때, 블록을 반환할 수 있을 지 없을지를 할당기가 검출할 것을 요구
- 묵시적 할당기는 가비지 컬렉터(garbage collector)라고 알려져 있다.
- 자바 같은 상위수준 언어들은 블록들을 반환시키기 위해 가비지 컬렉션을 사용한다.
01. malloc과 free 함수
(1) malloc 함수
#includef <stdlib.h>
void *malloc(size_t size);
- 32비트 모드에서 malloc은 주소가 항상 8의 배수인 블록을 리턴한다.
- 64비트 모드에서 주소는 항상 16의 배수이다.
- malloc은 리턴하는 메모리를 초기화하지 않는다.
- calloc() : 초기화한 동적 메모리를 원하는 함수를 사용한다.
- realloc() : 이전에 할당된 블록의 크기를 변경한다.
- 프로그램이 가용한 가상 메모리보다 더 큰 크기의 메모리 블록을 요청하는 경우, null을 리턴하고 errno를 설정한다.
(2) sbrk 함수
#include<unistd.h>
void *sbrk(intptr_t incr);
- sbrk 함수는 커널의 brk 포인터에 incr을 더해서 힙을 늘리거나 줄인다.
- 성공한다면 이전의 brk 값을 리턴, 아니면 -1 리턴하고 errno를 ENOMEM으로 설정
- 만일 incr이 0이면? : sbrk는 현재의 brk 값을 리턴
- 성공한다면 이전의 brk 값을 리턴, 아니면 -1 리턴하고 errno를 ENOMEM으로 설정
02. 왜 동적 메모리 할당을 사용해야할까?
메모리를 항상 정해두고 사용하다보면 추후에 프로그램의 사용자가 더 큰 파일을 지정하려고 한다면 유일한 대책은 더 큰값을 사용해서 다시 컴파일 하는 것이다. 따라서 프로그램을 실제 실행시키기 전에 자료구조의 크기를 알 수 없다면 동적으로 메모리를 할당하여 사용하는 것이 효율적이다. (아래 예시를 보면 MAXN은 임의적으로 정해둔 값이다.)
만일 사용자가 MAXN을 적은 크기를 쓰거나 큰 파일을 읽으려 한다면 비효율적인 코드가 될 것이다. 아래와 같은 간단한 예제는 문제가 안 될 수 있지만, 큰 규모의 소프트웨어 제품에서는 관리 하는데 어려움이 될 수 있다.
#include "caspp.h"
#define MAXN 15213
int array[MAXN];
int main(){
int i, n;
scanf("%d", &n);
if(n > MAXN)
app_error("INPUT FILE TOO BIG");
for(i = 0; i < n ;i++)
scanf("%d", &array[i]);
exit(0);
}
03. 할당기 요구사항과 목표
(1) 할당기 요구사항
- 임의의 요청 순서 처리하기 : 할당기는 할당과 반환요청의 순서에 대해서는 아무 가정도 할 수 없다.
- 요청에 즉시 응답하기 : 할당기는 요청을 할당하는 것에 대해 즉시 응답한다.
요청에 대해 버퍼하거나 리오더 하는것이 허락되지 않는다! (출처: thanks to ㅁㄱㅅ님)
- 힙만 사용하기 : 확장성을 위해 할당기가 사용하는 비확장성 자료 구조들은 힙 자체에 저장되어야 한다.
- 블록 정렬하기(정렬요건) : 할당기는 블록들을 이들이 어떤 종류의 데이터 객체라도 저장할 수 있도록 정렬
- 할당된 블록을 수정하지 않기 : 할당기는 가용 블록을 조작하거나 변경할 수만 있다.
(2) 할당기 목표
- 처리량 극대화하기
- 메모리 이용도 최대화하기
04. 단편화
(0) 단편화?
- 단편화는 메모리 할당 요청을 만족시킬 수 없을 때 일어난다.
(1) 내부 단편화
- 할당된 블록이 데이터 자체보다 더 클 때일어난다.
- 할당기는 정렬 제한사항을 만족시키기 위해서 사용자가 요청한 블록보다 블록의 크기를 증가시킬 수도 있다.
- 내부 단편화는 정량화하기 간단하다.
- 단순히 할당된 블록에 크기와 이들의 데이터 사이의 차이 합이다.
(2) 외부 단편화
외부 단편화는 할당 요청을 만족시키기 위한 가용메모리가 충분하지만, 가용할 수 있는 메모리 위치가 적절하지 않을 때 발생한다. 아래 그림을 보면 가용 가능한 블록은 6개이다. 총 24바이트의 여유 메모리가 있지만, 4블록과 2블록으로 나누어져 있기 때문에 24바이트의 블록을 할당할 수 없다.
외부 단편화는 내부 단편화보다 훨씬 더 측정하기 어렵다. 미래의 요청 패턴이 외부단편화에 영향을 미칠 수 있기 때문이다. 외부 단편화 측정의 어려움 때문에 할당기들은 대개 많은 수의 더 작은 가용블록들보다는 더 적은 수의 더 큰 가용 블록들을 유지하려는 방법들을 채택하고 있다.
'Computer Systems' 카테고리의 다른 글
🖥[CSAPP] 9장. Malloc Lab 명시적 가용(Explicit Free List)리스트 구현하기 (0) | 2022.11.01 |
---|---|
🖥[CSAPP] 9장. Malloc Lab 묵시적 가용 리스트 구현하기 (0) | 2022.10.30 |
🖥[CSAPP] 1장. 운영체제는 하드웨어를 관리한다. (0) | 2022.10.29 |
🖥[CSAPP] 1장. 캐시가 정말 중요할까? (0) | 2022.10.29 |
👩🏼💻[CSAPP] 어셈블리어 (0) | 2022.10.29 |
댓글