O segmento de mapeamento de memória e o heap crescem até se encontrarem?

0

Eu tento descobrir o intervalo do segmento de memória compartilhada, ou seja, o segmento de mapeamento de memória no layout de memória de um processo, de duas fontes abaixo.

De link , encontrei um diagrama de layout de memória de um processo

O segmento de mapeamento de memória e o heap crescem até se encontrarem?

Ou existe um limite para cada um dos dois segmentos crescer, semelhante ao RLIMIT_STACK para o segmento de pilha?

DainterfacedeprogramaçãodoLinux

Toallowspaceforheapandstackgrowth,sharedmemorysegmentsareattachedstartingatthevirtualaddress0x40000000.Mappedmappings(Chapter49)andsharedlibraries(Chapters41and42)arealsoplacedinthisarea.(Thereissomevariationinthedefaultlocationatwhichsharedmemorymappingsandmemorysegmentsareplaced,dependingonthekernelversionsandthesettingoftheprocess’sRLIMIT_STACKresourcelimit.)Theaddress0x40000000isdefinedasthekernelconstantTASK_UNMAPPED_BASE.

OsegmentodememóriacompartilhadacomeçaemTASK_UNMAPPED_BASEecresceparacima?

Observequeodiagramaanteriormostraqueosegmentodememóriacompartilhadacresceparabaixo,entãocresceparacimaouparabaixo?

Obrigado.

    
por Tim 02.09.2018 / 22:07

1 resposta

3

Existem alguns limites que se aplicam ao segmento mmap e ao segmento de heap. RLIMIT_AS determina o espaço de endereço disponível, em geral; Isso abrange todas as alocações de memória que um programa pode fazer. RLIMIT_DATA determina o tamanho máximo do segmento de dados.

O kernel verifica a expansão de pilha, mmap e brk (alocação de heap) contra esses limites. Ele também verifica as alocações contra segmentos potencialmente conflitantes, para que os segmentos nunca acabem se sobrescrevendo (veja, por exemplo, as verificações realizadas para alocação de heap com brk ). Se uma alocação for impossível, o programa é “informado” conforme apropriado: a biblioteca C retorna um erro ENOMEM para brk , o kernel mata o programa com um SIGSEGV se a pilha não puder ser expandida ...

Como o segmento de memória compartilhada (estritamente falando da perspectiva do kernel, área de memória virtual) cresce depende do layout da memória, que pode variar de um processo para outro. Na maioria das arquiteturas, os mapas de memória “herdados” resultam em alocação de baixo para cima, a partir de TASK_UNMAPPED_BASE ; mapas de memória não herdados resultam em alocação top-down. Veja arch_pick_mmap_layout() e mmap_is_legacy() na arquitetura x86 para um exemplo. Você pode alternar para o mapa de memória herdada usando setarch ' -L flag (veja abaixo um exemplo).

Na prática, você pode ver como o segmento cresce observando /proc/$$/maps e verificando os endereços das bibliotecas compartilhadas carregadas (se houver), v. sua ordem de carregamento. O vinculador dinâmico é sempre carregado primeiro; se tiver um endereço mais baixo do que outras bibliotecas, a alocação será de baixo para cima, caso contrário, será de cima para baixo. Compare a saída de cat /proc/self/maps e setarch x86_64 -L cat /proc/self/maps em um sistema x86 de 64 bits.

    
por 02.09.2018 / 23:03