Este artigo foi emprestado de: https://www.cnblogs.com/fengliu-/p/9243004.html
https://blog.csdn.net/wsq119/article/details/82110757
https://www.cnblogs.com/ wuchanming / p / 4339770.html
Diagrama de distribuição do espaço de endereço do processo:
Segmento de programa (Texto): O mapeamento do código do programa na memória, armazenando o código binário do corpo da função.
Dados inicializados (dados): os dados que foram inicializados para variáveis no início do programa.
Dados não inicializados (BSS): Os dados que não inicializaram as variáveis no início da operação do programa.
Stack: Armazena variáveis locais e temporárias.Quando a função é chamada, ela armazena o ponteiro de retorno da função, que é usado para controlar a chamada e o retorno da função. A memória é alocada automaticamente no início do bloco do programa, e a memória é automaticamente liberada no final.O modo de operação é semelhante à pilha na estrutura de dados.
Heap: Alocação de memória dinâmica de armazenamento, que requer alocação manual e liberação manual pelo programador. Observe que é diferente do heap na estrutura de dados e o método de alocação é semelhante a uma lista vinculada.
Mecanismo de alocação de memória inicial
No computador inicial, para executar um programa, todos esses programas eram carregados na memória e o programa era executado diretamente na memória, ou seja, os endereços de memória acessados no programa eram os endereços reais da memória física. Quando um computador executa vários programas ao mesmo tempo, deve-se garantir que a quantidade total de memória usada por esses programas seja menor que o tamanho da memória física real do computador.
Quando um programa executa vários programas ao mesmo tempo, como o sistema operacional aloca memória para esses programas? A seguir está um exemplo para ilustrar o método de alocação de memória naquele momento: o
tamanho total da memória de um computador é 128M, e agora dois programas A e B estão sendo executados ao mesmo tempo, A precisa ocupar 10M de memória e B precisa para ocupar 110 de memória. Quando o computador alocar memória para o programa, ele adotará este método: primeiro aloque os primeiros 10M na memória para o programa A e, em seguida, divida 110M dos 118M restantes na memória e aloque-os para o programa B. Esse método de alocação pode garantir que os programas A e B possam ser executados, mas essa estratégia simples de alocação de memória tem muitos problemas.
Segmentado
Para resolver os problemas acima, as pessoas pensaram em uma solução alternativa, que é adicionar uma camada intermediária e usar um método de acesso de endereço indireto para acessar a memória física. De acordo com este método, o endereço de memória acessado no programa não é mais um endereço de memória física real, mas um endereço virtual, e então o sistema operacional mapeia esse endereço virtual para um endereço de memória física apropriado. Desta forma, enquanto o sistema operacional lida com o mapeamento de endereços virtuais para endereços de memória física, ele pode garantir que os endereços de memória finalmente acessados por diferentes programas estejam localizados em áreas diferentes sem se sobreporem, e o efeito do espaço de endereço de memória o isolamento pode ser alcançado.
Quando um processo é criado, o sistema operacional aloca um espaço de endereço de processo virtual de 4 GB para o processo. A razão de ter 4 GB é porque em um sistema operacional de 32 bits, um ponteiro tem 4 bytes de comprimento e a capacidade de endereçamento de um ponteiro de 4 bytes é de 0x00000000 a 0xFFFFFFFF, e o valor máximo 0xFFFFFFFF representa uma capacidade de 4 GB . Em contraste com o espaço de endereço virtual, há também um espaço de endereço físico, que corresponde à memória física real. Se a memória 512M estiver instalada em seu computador, o intervalo desse espaço de endereço físico é 0x00000000 ~ 0x1FFFFFFF. Quando o sistema operacional mapeia um endereço virtual para um endereço físico, ele pode mapear apenas para este intervalo, e o sistema operacional pode mapear apenas para este intervalo. Quando um processo é criado, cada processo terá seu próprio espaço de endereço virtual de 4 GB. Deve-se notar que este espaço de endereçamento de 4GB é "virtual", não real, e cada processo só pode acessar dados em seu próprio espaço de endereçamento virtual, e não pode acessar dados em outros processos.Isso é alcançado por este método Isolamento de endereço entre processos.
A razão pela qual as pessoas desejam criar um espaço de endereço virtual é para resolver o problema de isolamento do espaço de endereço do processo. Mas se o programa deseja executar, ele deve rodar na memória real, portanto, uma relação de mapeamento deve ser estabelecida entre o endereço virtual e o endereço físico. Dessa forma, por meio do mecanismo de mapeamento, quando um programa acessa um valor de endereço no espaço de endereço virtual, é equivalente a acessar outro valor no espaço de endereço físico. As pessoas pensam em um método de segmentação, cuja ideia é fazer um mapeamento um-para-um entre o espaço de endereço virtual e o espaço de endereço físico. Por exemplo, um espaço de 10M no espaço de endereço virtual é mapeado para um espaço de 10M no espaço de endereço físico. Essa ideia não é difícil de entender: o sistema operacional garante que o espaço de endereçamento de diferentes processos seja mapeado para diferentes áreas no espaço de endereçamento físico, de forma que cada processo finalmente o acesse.
Os espaços de endereço físico são separados uns dos outros. Desta forma, o isolamento do endereço entre os processos é alcançado. Vamos dar um exemplo para ilustrar. Suponha que haja dois processos A e B. O tamanho da memória do processo A é 10M, seu espaço de endereço virtual é distribuído de 0x00000000 a 0x00A00000, a memória exigida pelo processo B é 100M e seu espaço de endereço virtual é distribuído de 0x00000000 a 0x06400000. Então, de acordo com o método de mapeamento segmentado, o processo A mapeia a área na memória física de 0x00100000 a 0x00B00000 e o processo B mapeia a área na memória física de 0x00C00000 a 0x07000000. Portanto, o processo A e o processo B são respectivamente mapeados para diferentes intervalos de memória e não se sobrepõem, realizando o isolamento do endereço. Do ponto de vista do programa de aplicação, o espaço de endereço do processo A é distribuído de 0x00000000 a 0x00A00000. Durante o desenvolvimento, os desenvolvedores só precisam acessar os endereços neste intervalo. O programa aplicativo não se importa se o processo A está mapeado para a área da memória física, portanto, o endereço de execução do programa é equivalente a ser determinado.
Embora esse método de mapeamento segmentado resolva o primeiro e o terceiro problemas mencionados acima, ele não resolve o segundo problema, ou seja, o problema da eficiência do uso da memória. No método de mapeamento segmentado, cada vez que a memória é trocada para dentro e para fora é o programa inteiro, o que irá causar um grande número de operações de acesso ao disco, resultando em baixa eficiência. Portanto, esse método de mapeamento ainda é um pouco áspero e a granularidade é relativamente grande. De fato, o funcionamento do programa possui características de localidade, em um determinado período de tempo, o programa acessa apenas uma pequena parte dos dados do programa, ou seja, a maior parte dos dados do programa não serão utilizados no um certo período de tempo. Com base nessa situação, as pessoas pensam em um método de segmentação e mapeamento de memória com uma granularidade menor, esse método é a paginação.
Paginação
O método básico de paginação é dividir o espaço de endereço em várias páginas. O tamanho de cada página é determinado pela CPU e, em seguida, o sistema operacional seleciona o tamanho da página. Atualmente, a CPU da série Inter suporta o tamanho de página de 4 MB ou 4 MB, enquanto o PC atualmente opta por usar 4 KB. De acordo com essa escolha, o espaço de endereço virtual de 4 GB pode ser dividido em 1.048.576 páginas e a memória física de 512M pode ser dividida em 1.31072 páginas. Obviamente, o número de páginas no espaço virtual é muito maior do que o número de páginas no espaço físico.
No método de segmentação, o programa é sempre carregado na memória cada vez que o programa é executado, mas o método de paginação é diferente. A ideia da paginação é alocar memória para a página usada quando o programa está em execução, e as páginas não usadas são temporariamente mantidas no disco rígido. Quando essas páginas são usadas, a memória é alocada para essas páginas no espaço de endereço físico e, em seguida, um mapeamento entre as páginas no espaço de endereço virtual e as páginas de memória física recém-alocadas é estabelecido.
O seguinte descreve a implementação do mecanismo de paginação, introduzindo o processo de carregamento de um arquivo executável. Um arquivo executável (arquivo PE) é, na verdade, uma coleção de dados e instruções compilados e vinculados. Também será dividido em várias páginas. Durante a execução do arquivo PE, a unidade que ele carrega na memória é a página. Quando um arquivo PE é executado, o sistema operacional primeiro cria um espaço de endereço virtual de processo de 4 GB para o programa. Conforme mencionado anteriormente, o espaço de endereço virtual é apenas uma camada intermediária. Sua função é usar um mecanismo de mapeamento para mapear o espaço de endereço virtual para o espaço de endereço físico. Portanto, criar um espaço de endereço virtual de 4 GB não é realmente criar espaço, mas A estrutura de dados necessária para criar esse mecanismo de mapeamento nada mais é do que a estrutura de dados do cabeçalho da página e da tabela da página.
Depois de criar a estrutura de dados exigida pelo espaço de endereço virtual, o processo começa a ler a primeira página do arquivo PE. A primeira página do arquivo PE contém informações como o cabeçalho do arquivo PE e a tabela de segmentos. De acordo com o cabeçalho do arquivo e a tabela de segmentos, o processo mapeia todos os segmentos no arquivo PE para as páginas correspondentes no espaço de endereço virtual (no Arquivo PE). O comprimento do segmento é um múltiplo inteiro do comprimento da página). Neste momento, as instruções e dados reais do arquivo PE não foram carregados na memória. O sistema operacional apenas estabelece a relação de mapeamento entre o arquivo PE e a página no espaço de endereço virtual do processo de acordo com o cabeçalho e outras informações de o arquivo PE. Quando a CPU deseja acessar um determinado endereço virtual usado no programa, quando a CPU descobre que o endereço não possui um endereço físico associado, a CPU pensa que a página onde o endereço virtual está localizado é uma página vazia, e a CPU pensa é uma falha de página (Falha de página), a CPU também sabe que o sistema operacional não alocou memória para a página PE, e a CPU retornará o controle ao sistema operacional. O sistema operacional então aloca uma página no espaço físico para a página PE e, em seguida, mapeia a página física com a página virtual no espaço virtual e, em seguida, retorna o controle para o processo, e o processo é reiniciado a partir da posição onde a página falha ocorreu agora mesmo. Como a memória foi alocada para essa página do arquivo PE neste momento, a falha de página não ocorrerá. Com a execução do programa, as falhas de página continuarão a ocorrer e o sistema operacional alocará as páginas físicas correspondentes para o processo atender às necessidades do processo.
A ideia central do método de paginação é que quando o arquivo executável é executado na xª página, uma página de memória y é alocada para a xª página, e então esta página de memória é adicionada à tabela de mapeamento do espaço de endereço virtual do processo Esta tabela de mapeamento é equivalente em uma função y = f (x). O aplicativo pode acessar a página y associada à página x por meio desta tabela de mapeamento.
Do exposto, podemos saber que, no processo de criação do processo,Todo o conteúdo do programa é mapeado para o espaço de memória virtual do processo. Para permitir que um grande programa seja executado em um espaço de memória física limitado, podemos carregar a parte inicial do programa no espaço de memória física para ser executado, porque o sistema operacional lida com o processo. Se você descobrir que o endereço físico não existe no projeto de conversão de endereço virtual em físico, uma falha de página (nopage) ocorrerá neste momento e, em seguida, o sistema operacional carregará o disco que não foi carregado na memória Os dados são carregados na memória física e a tabela da página do processo correspondente é atualizada . Você pode perguntar, se a memória física está cheia neste momento, o que o sistema operacional fará?
Vamos dar uma olhada em como o sistema operacional Linux lida com isso:
Se um processo deseja carregar uma página virtual na memória física, mas lá não é utilizável. Com páginas físicas gratuitas, o sistema operacional deve eliminar outras páginas da memória física para abrir espaço para esta página.
No sistema operacional Linux, a descrição da página física é a seguinte:
struct mem_map
{
1、本页使用计数,当该页被许多进程共享时计数将大于1
2、age描叙本页的年龄,用来判断该页是否为淘汰或交换的好候选
3、map_nr描叙物理页的页帧号
}
Se a página eliminada da memória física vier de um arquivo de imagem ou de dados e não tiver sido gravada, a página não precisa ser salva, ela pode ser descartada. Se um processo precisar da página, ele pode recuperá-la da imagem ou do arquivo de dados na memória.
No entanto, se a página foi modificada, o sistema operacional deve reter o conteúdo da página para que ela possa ser acessada posteriormente. Este tipo de página é denominado "página suja". Quando é apagada da memória, será salva em um arquivo especial denominado arquivo de troca.
Em relação à velocidade do processador e da memória física, leva muito tempo para acessar o arquivo de troca, e o sistema operacional deve gastar muito tempo com a questão de gravar páginas no disco e recuperar a memória quando elas são usadas novamente.
Se o algoritmo usado para determinar qual página é eliminada ou trocada não for eficiente o suficiente, uma situação chamada "jitter" pode ocorrer. Nesse caso, a página é sempre gravada no disco e lida de volta, e o sistema operacional está muito ocupado para realizar um trabalho real.
O Linux usa a técnica de paginação "Menos Usado Recentemente (LRU)" para escolher qual página pode ser excluída do sistema. Cada página neste sistema de design tem uma "idade", e a idade muda conforme a página é acessada. Quanto mais visitada a página, mais jovem ela é; quanto menos visitada, mais velha ela é. A página antiga é a melhor página candidata para troca.
organização de armazenamento virtual linux
Cada processo (thread) corresponde a um descritor de processo (task_struct), cada descritor de processo tem um descritor de memória (mm_struct) que é o espaço de endereço de processo exclusivo e o descritor de memória contém uma lista vinculada de área de memória virtual (vm_area_struct) é usada para identificar a área usada no espaço de endereço