Quando o heap é usado para alocação de memória dinâmica?

1

O título desta pergunta é muito básico, mas não consegui encontrar uma resposta em nenhum lugar. Cada postagem sobre alocação de memória parece explicar como mmap é usado ou como sbrk foi usado, sem considerar como isso pode ser contextualizado com o heap.

Eu percebi que o heap desempenha um papel quase insignificante nas alocações de memória - na verdade, não tenho certeza do que ele faz: D, e peço que alguém me confunda.

Isso é o que eu entendo:

1) Quando a memória é malocada, o final do segmento de dados não inicializado, o BSS, é expandido. Essa expansão (que move um endereço x para, digamos, x-n ) ocorre como resultado de uma chamada para sbrk . Neste modelo, a memória é alocada no n bytes (assumindo que cada endereço está em correspondência com um byte) que sbrk diminuiu a posição do cabeçalho do segmento BSS. Este modelo está agora obsoleto. Alguns definem o heap como o espaço que é o agregado de todas essas expansões. Outros não - no último caso, o que o heap faz?

2) Nos esquemas modernos de alocação de memória, existe um heap (por que razão, novamente, não tenho certeza). Para alocar memória, malloc internamente usa mmap para armazenar dados em regiões de memória que são uma coleção de páginas. Essas regiões de memória são independentes do heap.

TLDR:

For old sytems: If memory allocations are stored into address space that is obtained after increasing the offset of the end BSS, then does a heap serve any purpose?

For newer systems: Granted that mmap is mainly used for memory allocations, then what purpose does the heap serve?

In both cases, does the heap really do anything useful?

    
por Muno 17.12.2017 / 15:56

2 respostas

1

mmap e sbrk são as chamadas de sistema que o kernel fornece para alocar espaço de endereçamento aos processos. Essas chamadas alteram o mapeamento de endereços virtuais para quadros de páginas físicas. Endereçamento de memória fora dos limites de endereço desses mapeamentos é um não-não estrito e resulta em uma falha de segmentação. Essa é a interface de baixo nível que o kernel fornece para um processo, e a área de memória que termina com o endereço brk é comumente chamada de heap.

O kernel não sabe nada sobre malloc ou free , estas são funções da biblioteca na libc. O Libc mantém estruturas de dados e registra quais áreas de memória estão livres do ponto de vista da alocação de memória, por exemplo, como o. Uma chamada para malloc não necessariamente resulta em uma chamada para sbrk ou mmap (dependendo de como o Libc implementa a alocação de memória dinâmica) para expandir os mapeamentos, se uma chamada para malloc puder ser satisfeita reutilizando os liberados anteriormente áreas de memória.

    
por 17.12.2017 / 16:30
0

"O heap" é uma ideia de alto nível, não uma implementação de baixo nível. Em C, o heap é qualquer pool de memória que malloc() usa para fornecer alocações.

Aqui está uma implementação divertida e simples do alocador de memória:

static char *heap[1000000];
int top = 0;

void *malloc(int size) {
    void *ret = &heap[top];
    top += size;
    return ret;
}

void free(void *ptr) {
    /* Eh; freeing is too hard */
    return;
}

Este é um alocador horrível, mas para o tipo certo de programa e se o seu sistema e compilador estão perdoando coisas como alinhamento de memória , isso funciona. Seu heap é o array heap[] , e ele é compilado em tempo de compilação usando uma declaração de matriz, em vez de montar um com sbrk() ou mmap() .

Um alocador "real" funciona da mesma maneira. Quando malloc() é chamado, ele ocupa uma pequena parte do pool de memória (heap) e o reserva para essa alocação. Existem duas diferenças importantes:

  • O alocador real sabe como free() uma alocação para poder usá-lo novamente mais tarde.
  • O alocador real pode aumentar o tamanho de seu heap, solicitando ao sistema operacional mais memória (usando sbrk() ou mmap() ) quando todos os blocos existentes estiverem cheios.
por 22.12.2017 / 22:21