본문 바로가기
SP

[sp] Dynamic Memory Allocation : Advanced (2)

by 녕인뉸 2022. 5. 26.

1. Segregated List (Seglist) Allocators

(1) 블럭의 각 크기별 클래스는 각자의 free list를 가짐

malloc(6)을 했을 때 알맞는 클래스를 찾아서 6만큼 할당하고,

나머지 남은 블럭은 이 블럭의 사이즈에 맞는 클래스에 연결해줌

 

(2) 종종 각각의 작은 사이즈에 대한 분리된 클래스를 가짐

(3) 큰 사이즈 : 각 2의 지수 크기의 블럭 클래스

 

(4) 크기가 n인 블럭을 할당하기 위해

 - n보다 큰 사이즈의 블럭에 대한 적절한 free list를 찾음

 - 만약 적절한 크기의 블럭을 찾았다면 -> 블럭을 분리하고, 이 분리된 블럭 중 할당되지 않은 블럭은 적절한 클래스를 찾아 이어줌 (선택)

 - 만약 블럭이 없으면, 다음의 큰 클래스에 이 과정을 반복

 

(5) 블럭이 없으면

 - OS로부터 추가적인 힙 메모리를 요청 (sbrk() 사용)

 - 이 새로운 메모리로부터 n 바이트의 블럭을 할당

 - 나머지는 더 큰 사이즈에 클래스에 단일 free block으로 둠

 

기존의 heap 공간에서 원하는 크기만큼 할당할 블럭이 없으면 sbrk()를 사용하여 brk를 증가시키면서 힙 공간을 늘려줌

거기서 원하는 만큼 할당을 해주고, 남은 힙 공간은 하나의 free block으로 만들어서

이렇게 9-info와 같은 적절한 크기의 클래스를 찾아서 이어줌

 

 

(6) 블럭 할당해제

 - 적절한 리스트에 합치고 넣어줌

 

(7) seglist allocator의 장점

 - 높은 throughput : 2의 지수 크기의 클래스에 대한 log 시간

 - 더 좋은 메모리 이용량 : fragmentation이 적음, segregated free list의 first-fit 서치는 전체 힙의 best-fit에 가까움

                                 : 극단적인 경우 - 각 블럭에 각 사이즈 클래스를 주는 것은 best-fit과 동일

 

 

 

 

2. Garbage collection

(1) Implicit memory management : Garbage collection

 - Garbage collection : 할당된 저장소인 힙의 자동 회수는 free할 필요 없음

void foo() {
    int *p = malloc(128);
    return; /* p block is now garbage */
}

int형의 포인트 p는 스택 안에서 힙의 32 x 4 = 128만큼의 int 배열을 포인트하고 있음

만약 foo가 종료되면 스택이 포인트하고 있는 것이 해제되면서 힙 안에 메모리 누수가 발생할 수 있는데 이를 garbage

 

(2) 어떻게 메모리 매니저는 메모리가 free된 것을 알까

- 일반적으로 조건에 따라 다르기 때문에 알 수 없음

- 하지만 특정 블럭에 대한 포인터가 없으면, 특정 블럭을 사용할 수 없음

 

(3) 포인터에 대한 가정

- 메모리 매니저는 non-pointer로부터 포인터를 구분

- 모든 포인터는 블럭의 시작 지점을 가리킴

- 포인터를 숨길 수 없음

(ex. int에 대한 포인터를 합치고 돌아옴)

 

 

 

 

3. Memory as graph

(1) 메모리는 방향 그래프로 봄

- 각 블럭은 그래프의 노드

- 각 포인터는 그래프의 엣지

- 힙에 없는 위치에서 힙에 대한 포인터를 포함하는 위치: root node

(ex. 레지스터, 스택의 위치, 글로벌 변수)

루트에서부터 노트까지의 path가 있으면 노드(블럭)은 reachable

non-reachable 노드는 garbage

 

리턴하면서 스택에서 힙 안의 노드를 가리키고 있던 포인터가 해제했을 경우,

힙 안의 노드들은 non-reachable이 됨

 

배열로 나타내면, 배열 안에는 reachable한 블럭과 non-reachable한 블럭이 섞여 있는데

non-reachable한 블럭은 free해줌

 

 

 

4. Mark and sweep collecting

(1) malloc / free package의 top에 빌드 가능

- 공간이 부족할 때까지, malloc을 사용하여 할당

 

(2) 공간 부족할 때

- 각 블럭의 헤드에서 추가적인 mark bit를 사용

- Mark : root에서 시작하며 각각의 reachable한 블럭에 mark bit를 세팅

- Sweep : 모든 블럭을 스캔하고 mark가 없는 블럭을 free

빨간 색 블럭들은 reachable

sweep에서 모든 블럭을 돌면서 mark bit가 없는 블럭은 free

 

(3) 간단한 구현을 위한 가정

- Application

 : new(n) - 모든 위치가 지워진 새로운 블럭에 포인터를 리턴

 : reab(b, i) - 블럭 b의 위치 i을 레지스터로 읽음

 : write(b, i, v) - 블럭 b의 위치 i로 v를 씀

 

- 각 블럭은 header word를 가짐

 : 블럭 b에 대해 b[-1]로 주소 지정

 : 다른 collector에서 다른 목적으로 사용

 

- GC에 의해 사용되는 명령어

 : is_ptr(p) - p가 포인터인지를 결정

 : length(b) - 블럭 b의 길이를 리턴 (헤더 포함하지 않음)

 : get_roots() - 모든 루트를 리턴

 

 

(4) Mark and sweep

- Mark

메모리 그래프의 깊이 우선 탐색을 사용하여 Mark

ptr mark(ptr p) {
    if (!is_ptr(p)) return; // do nothing if not pointer
    if (markBitSet(p)) return; // check if already marked
    setMarkBit(p); // set the mark bit
    for (i=0; i < length(p); i++) // call mark on all words
    	mark(p[i]); // in the block
    return;
}

포인터가 아니면 리턴하고 포인터이면 밑으로

mark bit가 세팅되어 있으면 리턴 그렇지 않으면,

포인터 p에 mark bit을 세팅하고

p의 길이만큼 블럭을 돌면서 깊이 우선 탐색을 하면서 위 과정 반복

 

 

- Sweep

다음 블럭을 찾기 위해 길이를 사용하여 sweep

ptr sweep(ptr p, ptr end) {
    while (p < end) {
    	if markBitSet(p)
    		clearMarkBit();
    	else if (allocateBitSet(p)) //non-reachable
    		free(p);
    	p += length(p);
}

모든 블럭을 스캔하면서,

p에 mark bit가 세팅되어있으면 mark bit를 지움

p에 비트가 세팅되어 있지 않고 비트가 할당되어 있으면 free

p에 p의 길이만큼 더해주면서 다음 블럭에서 위 과정 반복

 

 

 

(5) Conservative Mark & Sweep in C

- C 프로그램에서의 conservative garbage collector

 : is_ptr()은 포인터가 메모리의 할당된 블럭을 가리키는지 확인함으로써 워드가 포인터인지를 결정

 : C 포인터에선 블럭의 중앙을 포인트

 

- 그럼 어떻게 블럭의 시작을 찾음?

 : 균형 이진트리를 사용하여 할당된 모든 블럭을 추적

 (key : start-of-block)

 : 균형 트리 포인터는 헤더에 저장될 수 있음 (추가적인 2 word 사용)

 

left가 allocated돼 있다고 가정

-> mark 수행

-> sweep 시 할당돼 있으므로 free하지 않음 => conservative

'SP' 카테고리의 다른 글

[SP] Linking (2)  (0) 2022.06.07
[SP] Linking  (0) 2022.06.03
[sp] Dynamic Memory Allocation : Advanced (1)  (0) 2022.05.25
[sp] Dynamic Memory Allocation (3)  (0) 2022.05.24
[sp] Dynamic Memory Allocation (2)  (0) 2022.05.23