일정한 시간 작업으로 영리한 메모리 관리?


18

고정 크기 블록과 관련된 두 가지 기본 메모리 할당 작업을 수행 할 수있는 메모리 세그먼트 (필요한 경우 파일과 같이 크기가 커지거나 줄어들 수 있음)를 고려해 보겠습니다.

  • 하나의 블록 할당
  • 더 이상 사용되지 않는 이전에 할당 된 블록을 해제합니다.

또한 필요에 따라 메모리 관리 시스템은 현재 할당 된 블록을 이동할 수 없습니다. 인덱스 / 주소는 변경되지 않아야합니다.

가장 순진한 메모리 관리 알고리즘은 글로벌 카운터 (초기 값 0)를 증가시키고 새 값을 다음 할당을위한 주소로 사용합니다. 그러나 할당 된 블록이 몇 개만 남아 있으면 세그먼트를 단축 할 수 없습니다.

더 나은 접근 방법 : 카운터를 유지하되 할당 해제 된 블록 목록 (일관된 시간에 수행 할 수있는 목록)을 유지하고 비어 있지 않은 한 새 할당의 소스로 사용하십시오.

다음은? 메모리 세그먼트를 가능한 한 짧게 유지하는 일정한 시간 할당 및 할당 해제의 제약으로 수행 할 수있는 영리한 것이 있습니까?

(목표는 가장 작은 주소로 현재 할당되지 않은 블록을 추적하는 것이 될 수 있지만, 일정한 시간에 실현 가능하지 않은 것 같습니다 ...)


이전에 수행 한 일부 할당 / 할당 해제로 인해 목록이 커지거나 줄어들 수 있으므로 목록 확인이 더 이상 일정하지 않습니까?
Sim

@ Sim, 나는 그것이 링크 된 목록이라고 가정하고 그것으로 작업은 항상 일 것입니다. 왜냐하면 항상 머리로만 작업하기 때문입니다. 영형()
svick

"더 나은 접근 방식"은 이미 최적의 메모리 양을 사용한다고 생각합니다. 즉, 사용 가능한 블록이 있으면 추가 메모리를 할당하지 않습니다. "영리한"접근 방식이 어떻게 향상 될 것이라고 상상하십니까? 할당 해제 후 세그먼트를 축소 할 수있는 가능성을 높이기 위해 처음에 가깝게 할당해야한다는 의미입니까?
svick

@ Sim : 죄송합니다. 스택이라는 용어를 사용해야했을 것입니다 (그러나 혼란 스러울 수 있다고 생각했습니다), 'deallocate'는 푸시되고 'allocate'는 팝입니다. 둘 다 일정한 시간입니다.
Stéphane Gimenez

실시간 제약 조건이 있거나 상각 된 상수 시간으로 괜찮습니까? 대답은 매우 다를 수 있습니다.
Gilles 'SO- 악마 그만해'

답변:


11

고정 크기 블록을 사용하면 설명 한 것은 무료 목록 입니다. 이것은 다음과 같은 트위스트를 갖는 매우 일반적인 기술입니다. 사용 가능한 블록 목록은 사용 가능한 블록 자체에 저장됩니다. C 코드에서는 다음과 같습니다.

static void *alloc_ptr = START_OF_BIG_SEGMENT;
static void *free_list_head = NULL;

static void *
allocate(void)
{
    void *x;

    if (free_list_head == NULL) {
        x = alloc_ptr;
        alloc_ptr = (char *)alloc_ptr + SIZE_OF_BLOCK;
    } else {
        x = free_list_head;
        free_list_head = *(void **)free_list_head;
    }
    return x;
}

static void
release(void *x)
{
    *(void **)x = free_list_head;
    free_list_head = x;
}

할당 된 모든 블록의 크기가 동일하고 크기가 포인터 크기의 배수이므로 정렬이 유지되는 한 잘 작동합니다. 할당 및 할당 해제는 일정 시간 (즉, 메모리 액세스 및 기본 추가와 같이 일정한 시간)입니다. 최신 컴퓨터에서 메모리 액세스에는 캐시 미스 및 가상 메모리가 포함될 수 있으므로 디스크 액세스가 가능하므로 "일정한 시간" 꽤 클 수 있습니다). 메모리 오버 헤드가 없습니다 (블록 당 추가 포인터 또는 이와 유사한 것 없음; 할당 된 블록이 연속적 임). 또한 할당 포인터는 한 번에 많은 블록을 할당해야하는 경우에만 주어진 지점에 도달합니다. 할당이 사용 가능 목록을 선호하므로 현재 포인터 아래의 공간이 클럭이 가득 찬 경우에만 할당 포인터가 증가합니다. 그런 의미에서, 기술.

감소빈 블록은 빈 목록을 따라야 확실하게 식별 될 수 있기 때문에 릴리스 후의 할당 포인터는 더 복잡 할 수 있습니다. 가능할 때 큰 세그먼트 크기를 줄이는 것이 중요하다면 더 많은 오버 헤드와 함께 대체 기술을 사용할 수 있습니다. 할당 된 두 블록 사이에 "구멍"을 넣습니다. 구멍은 메모리 순서로 이중 연결 목록과 함께 연결됩니다. 구멍의 시작 위치와 메모리에서 구멍의 시작 위치를 알고 있으면 구멍 크기를 찾을 수 있도록 구멍에 대한 데이터 형식이 필요합니다. 그런 다음 블록을 해제하면 다음 구멍과 이전 구멍과 병합하여 모든 구멍의 순서가 지정된 목록을 다시 작성 (일정 시간)하는 구멍을 작성합니다. 오버 헤드는 할당 된 블록 당 약 2 개의 포인터 크기 워드입니다. 그러나 그 가격으로 "최종 홀"의 발생, 즉 큰 세그먼트 크기를 줄일 수있는 기회를 확실하게 감지 할 수 있습니다.

가능한 많은 변형이 있습니다. 좋은 입문서는 Wilson 등의 Dynamic Storage Allocation : A Survey and Critical Review 입니다.


4
일정 시간 내에 할당 해제 사이트에 가장 가까운 구멍을 어떻게 찾습니까?
Raphael

1
내가 설명하는 두 번째 방법에서, 구멍은 헤더 (구멍 목록에 대한 포인터 쌍)와 0, 하나 이상의 데이터 블록을위한 공간입니다. 할당 된 두 블록 사이 에는 구멍 헤더만으로 구성된 미세 구멍이라도 항상 구멍이 있습니다. 따라서 가장 가까운 구멍을 쉽게 찾을 수 있습니다. 구멍 바로 앞과 뒤에 있습니다. 물론, 마이크로 홀은 프리리스트 (할당 가능한 홀리스트)의 일부가 아닙니다. 그것을 보는 또 다른 방법은 모든 블록과 모든 (마이크로가 아닌) 구멍에 헤더를 추가하는 것입니다 (16 비트 Ms-Dos 아래의 할당은 그렇게 작동했습니다).
Thomas Pornin

4

이 답변은 일반적인 메모리 관리 기술에 관한 것입니다. 모든 블록의 크기가 같고 정렬 된 경우에 대한 질문이 누락되었습니다.


알아야 할 기본 전략은 first-fit, next-fit, best-fit 및 buddy system 입니다. 내가 가르친 과정에 대해 짧은 요약을 한 번 썼다 . 나는 거기에 상당히 철저한 조사 를 지적한다 .

실제로 이러한 기본 전략의 다양한 수정 사항을 볼 수 있습니다. 그러나 이것들 중 어느 것도 실제로 일정한 시간이 아닙니다! 제한된 양의 메모리를 사용하는 동안 최악의 경우에는 가능하지 않다고 생각합니다.


흥미롭게도 자세한 내용을 읽어야합니다. 그러나 이러한 시스템은 일정하지 않은 크기 할당을 처리하는 것으로 보이며, 이는 내가 직면 한 문제가 아닙니다.
Stéphane Gimenez

권리. 죄송합니다. 질문을 너무 빨리 읽었습니다.
rgrig

영형(lg)

가장 작은 주소의 s /
small

2

상각 분석 및 특히 ​​동적 배열을 살펴볼 수 있습니다 . 모든 단계에서 일정한 시간 안에 작업이 실제로 수행되지 않더라도 장기적으로는 실제로 작동하는 것처럼 보입니다.


2
그리고 동적 배열이 메모리 할당에 정확히 어떻게 도움이됩니까?
svick

같은 종류의 알고리즘을 사용하여 인접한 셀 청크를 (de) 할당합니까? 전체 파일은 더 큰 덩어리의 링크 된 목록입니다.
gallais
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.