4.4. Memória Virtual: Os Detalhes

Primeiro, devemos introduzir um novo conceito: espaço de endereço virtual. O espaço de endereço virtual (virtual address space) é a quantidade máxima de espaço de endereço disponível para uma aplicação. O espaço de endereço virtual varia de acordo com a arquitetura e sistema operacional da máquina. O espaço de endereço virtual depende da arquitetura porque é esta que define quantos bits estão disponíveis para propósitos de endereçamento. O espaço de endereço virtual também depende do sistema operacional porque a maneira através da qual este foi implementado pode introduzir limites adicionais além ou aquém daqueles impostos pela arquitetura.

A palavra "virtual" do espaço de endereço virtual significa que este é o número total das localidades da memória disponíveis para uma aplicação que podem ser exclusivamente endereçadas, e não a quantidade de memória física instalada no sistema, nem dedicada à aplicação num determinado momento.

No caso de nossa aplicação exemplo, seu espaço de endereço virtual é 15000 bytes.

Para implementar a memória virtual é necessário que o sistema do computador tenha hardware para a administração de memória especial. Este hardware é geralmente conhecido como uma MMU (Memory Management Unit ou Unidade de Administração de Memória). Sem uma MMU, quando a CPU acessa a memória RAM, as localidades reais da RAM nunca mudam — o endereço de memória 123 é sempre a mesma localidade física dentro da RAM.

No entanto, com uma MMU, os endereços de memória passam por uma fase de tradução antes de cada acesso à memória. Isso significa que o endereço de memória 123 pode ser direcionado ao endereço físico 82043 uma vez e ao endereço físico 20468 na próxima vez. No desenrolar do processo, a sobrecarga de registrar individualmente as traduções dos bilhões de bytes de memória de virtual para físico seria muito grande. Ao invés disso, a MMU divide a RAM em páginas — seções contíguas de memória de tamanho determinado, que são encaradas pela MMU como entidades separadas.

Manter o registro destas páginas e de suas traduções de endereços pode soar como um passo adicional desnecessário e confuso. No entanto é crucial para implementar a memória virtual. Por este motivo, considere o seguinte ponto:

Se pegarmos nossa aplicação hipotética com 15000 bytes de espaço de endereço virtual, assuma que os primeiros dados de acesso à instrução da aplicação estão armazenados no endereço 12374. Entretanto, assuma também que nosso computador tenha somente 12288 bytes de memória RAM física. O que acontece quando a CPU tenta acessar o endereço 12374?

O que acontece é conhecido como uma falha de página (page fault).

4.4.1. Falhas de Página

Uma falha de página é a sequência de eventos que ocorre quando um programa tenta acessar os dados (ou código) que está em seu espaço de endereço, mas não está localizada na RAM do sistema no momento. O sistema operacional deve resolver as falhas de página tornando a memória dos dados acessados residente de alguma maneira, permitindo ao programa continuar a operação como se a falha de página nunca tivesse ocorrido.

No caso de nossa aplicação hipotética, a CPU apresenta primeiro o endereço desejado (12374) à MMU. No entanto, a MMU não possui tradução para este endereço. Sendo assim, interrompe a CPU e faz com que o software, conhecido como 'fault handler', seja executado. O fault handler então determina o que deve ser feito para resolver esta falha de página. É possível:

Apesar das três primeiras ações serem relativamente simples, a última não é. Para esta precisamos cobrir alguns tópicos adicionais.

4.4.2. O Conjunto de Trabalho

O grupo de páginas de memória física correntemente dedicado a um processo específico é conhecido como grupo de trabalho (ou working set) para este processo. O número de páginas do grupo de trabalho pode aumentar e diminuir, dependendo da disponibilidade geral das páginas do sistema todo.

O grupo de trabalho aumenta com as falhas de página de um processo. O grupo de trabalho diminui conforme a quantidade de páginas livres diminui. Para impedir que a memória acabe completamente, as páginas devem ser removidas dos conjuntos de trabalho do processo e transformadas em páginas livres, disponíveis para uso posterior. O sistema operacional diminui os conjuntos de trabalho dos processos ao:

Para determinar os conjuntos de trabalho apropriados para todos os processos, o sistema operacional precisa registrar as informações de uso de todas as páginas. Desta maneira, o sistema operacional determina quais páginas estão sendo ativamente usadas (e devem permanecer residentes na memória). Na maioria dos casos, algum tipo de algoritmo recém-usado determina quais páginas são removíveis dos conjuntos de trabalho do processo.

4.4.3. Swapping

Apesar do swapping (gravar páginas modificadas no espaço swap do sistema) ser uma parte normal da operação de um sistema, é possível que haja swapping em demasia. A razão para ficar atento para o swapping excessivo é que a situação a seguir pode ocorrer facilmente, diversas vezes:

Se esta sequência de eventos for espalhada, é conhecida como thrashing e é um sinal de memória RAM insuficiente para a atual carga de trabalho. O thrashing é extremamente prejudicial ao desempenho do sistema, já que a carga da CPU e I/O que pode ser gerada numa situação como esta rapidamente compensa a carga imposta pelo trabalho real de um sistema. Em casos extremos, o sistema talvez não execute nenhum trabalho útil, gastando todos os seus recursos movendo páginas da e para a memória.