TÓPICOS 4.1 Introdução 4.2 Esquema de organização de memória a) Carregamento de Código b) Relocação c) Unidade de Gestão Memória 4.3 Swapping 3.4 Paginação 4.5 Segmentação 4.6 Alocação de Memória 4.7 Memória virtual Objectivos
Apresentar uma descrição pormenorizada das várias formas de
organização da memória;
Comparar várias técnicas de gestão de memória, nomeadamente
segmentação e paginação. Introdução
Como sabemos, os computadores utilizam uma hierarquia de memória
em sua organização, combinando memórias voláteis e não-voláteis, tais como: memória cache, memória principal e memória secundária. Ao sistema operacional é destinada a função de coordenar e gerir a utilização dessas memórias de forma eficiente. Este serviço é implementado pelo sistema operacional através do gestor de memória. Função do Gestor de Memória
O gestor de memória controla quais partes da memória estão sendo
utilizadas e quais não estão. Além disso, ele é responsável por alocar espaço em memória aos processos que serão executados e liberar as posições de memória ocupadas quando os processos são finalizados. Uma outra funcionalidade do gestor de memória é controlar o swapping de informação, constante na execução das aplicações que veremos mais adiante. Conceitos A memória principal, os registos e o cache são os únicos dispositivos de armazenamento que o CPU pode aceder directamente. Quando um programa é executado, o seu código tem portanto de ser trazido de disco para a memória central. A imagem do processo é carregada em memória. Para que o processo possa ser carregado em memória é necessário atribuir-lhe um espaço. Pode ser em qualquer zona da memória física que esteja livre designado por espaço de endereçamento físico do processo. Uma vez que existem inúmeros processos carregados simultaneamente em memória (residentes): a) Os processos residentes em memória devem ter espaços físicos distintos. b) Têm de existir mecanismos de protecção da memória para assegurar a separação entre eles. Como é que cada processo sabe qual é o seu espaço de endereçamento físico? => Ligação entre Instruções e Memória Ligação de Instruções e Dados à Memória A ligação das Instruções e Dados a Endereços Físicos da Memória podem ser feitos em três alturas distintas: a) Na compilação: Se os endereços de memória são conhecidos à priori, o código pode gerado de forma absoluta mas se o endereço de início muda, terá de ser recompilado. b) No carregamento: Se os endereços da memória onde o processo vai ser carregado não são conhecidos no momento da compilação, o código é gerado em modo relativo. c) Na execução: Se o processo pode ser carregado em vários endereços memória diferentes durante a sua execução, a ligação aos endereços não pode ser realizada de forma definitiva. Nesse dois últimos casos é necessário suporte do hardware para realizar o mapeamento de endereços: Registos de Base e Limite Unidade de Gestão Memória Em geral, os programas precisam ser compilados para que possam ser executados no sistema computacional. Várias actividades ocorrem entre o instante em que o mesmo é compilado e o momento em que ele inicia sua execução: Geração do código objecto, Código executável, Alocação em memória, Nova entrada no PCB, Inserção da referência do processo na fila de apto, etc. O mecanismo tradicional de transformação de programas em processos é ilustrado abaixo: Mecanismo Básico de Relocação
A todos os endereços lógicos gerados pelo CPU é adicionado o valor
contido num registo de relocação Mecanismo Básico de Limitação É também necessário limitar o espaço de endereçamento lógico a que um processo pode aceder Para isso são utilizados os dois registos base e limite Mecanismo Básico de Protecção Com os Registos de Base e Limite é possível implementar um esquema de protecção muito simples: Quando o endereço gerado pelo CPU é inferior à base ou superior ao limite, é gerada uma excepção para o sistema operativo. Para cada processo são carregados valores diferentes nos registos. Unidade de Gestão de Memória (Memory Management Unit (MMU) A MMU é um módulo de hardware que faz o mapeamento entre os endereços lógicos (end. da memória virtual) e os endereços físicos da memória (RAM), ou seja, é um dispositivo que transforma endereços virtuais em endereços físicos. Para isso, a MMU normalmente traduz número de páginas virtuais para número de páginas físicas utilizando uma cache chamada Translation Lookaside Buffer (TLB). Na figura abaixo temos ilustrado o mecanismo de tradução dos endereços. Unidade de Gestão de Memória (UGM) É um dispositivo hardware que mapeia endereços lógicos para físicos Num sistema com MMU, o conteúdo dos registo de relocação é utilizado para modificar todos os endereços (lógicos) gerados por um processo antes de serem enviados para a memória física. O programa utilizador só conhece endereços lógicos, nunca conhece o endereço físico real. Existem inúmeros tipos de MMU (ou UGM) Inicialmente simples, baseada em registos de relocação Constituída depois por um chip dedicado com mais funções. Actualmente faz parte do chipset da maioria dos processadores, tendo-se tornado bastante complexo de utilizar e programar. A memória principal é geralmente dividida em duas partições: O Sistema Operativo, geralmente carregado a partir do início da memória, contendo o vector de interrupções. Os Processos dos utilizadores carregados na restante zona sendo necessário alocar memória para os conter. Os registos de relocação da MMU são utilizados para impedir os processos de acederem ao espaço uns dos outros e ao do sistema. O Registo de Base contém sucessivamente o endereço de início de cada processo activo. O registo de Limite contém o valor máximo do intervalo de endereços lógicos autorizados para cada processo. Todos os endereços acedidos pelo processo devem estar contidos entre o valor de base e o de limite, caso contrário é gerada uma excepção de acesso inválido. Os endereços são mapeados pela UGM dinamicamente. Partições Fixas e Variáveis Tradicionalmente os SO utilizavam partições de memória de tamanho fixo A memória era dividida em partições de vários tamanhos, de comprimento fixo. A memória não alocada numa partição não pode ser utilizada enquanto a partição estiver ocupada, provocando fragmentação do espaço de alocação. A organização da memória passa a ser realizada em partições de tamanho variável Nos sistemas mais recentes com características interactivas, o espaço da memória utilizada pelos processos pode variar muito no decorrer da sua execução. As partições podem ser agregadas ou separadas segundo as necessidades dos processos. Neste caso a fragmentação só depende do algorítmo de alocação Mecanismos de Particionamento Existem várias formas de particionar o espaço memória, que dependem sobretudo do tipo de Unidade de Gestão Memória utilizada: O mecanismo mais simples consiste na utilização de dois registos base e limite, que só permitem alocação contínua de toda a memória de um processo. Com a evolução do hardware, mecanismos mais complexos têm sido desenvolvidos e integrados pelos SO ao longo dos tempos. Utilização de múltiplos registos de relocação, permitindo distinguir várias zonas distintas no espaço de um processo: Segmentação Decomposição do espaço lógico e físico em inúmeras pequenas zonas independentes da natureza do seu conteúdo: Paginação 3.2- Swapping Com partições fixas um processo é carregado numa partição quando chega à cabeça da fila correspondente, e depois fica em memória até terminar. Se as necessidades de memória dos processos forem muito variáveis, a memória física pode tornar-se insuficiente para todos os processos. Uma solução possível é o recurso a swapping: Passar um processo para o disco (swap out) e, posteriormente Transferi-lo de novo do disco para a memória (swap in) Definição
Entende-se por Swapping “Espaço de troca”- Como sendo o espaço
ocupado no disco pelos processos que aí estão guardados, pois foram retirados da memória devido a uma troca. Os algorítmos para gerir o espaço alocado em disco para swap são os mesmos apresentados para a gestão de memória. Também é conhecido como: Alocação de Espaço de Troca A diferença é que em alguns sistemas, cada processo tem no disco um espaço reservado para o mesmo e na memória ele é constantemente mudado de lugar. Além disso, como os discos são dispositivos de bloco, a quantidade de espaço reservado para os processos no disco deverá ser múltipla do tamanho do bloco. Com swapping o número, localização e tamanho das partições varia dinamicamente: + melhora a utilização da memória; - torna a gestão de memória mais complexa. Contudo swapping pode conduzir à fragmentação da memória: + Pode ser atenuada usando compactação; - Mas compactação consome bastante CPU; Se o processo crescer em demasia e não houver mais memória para alocar, pode-se passá-lo para o disco (swap-out); Se disco estiver cheio, pode-se bloquear processo ... Mas nesse caso o processo ocupará memória. Em Resumo: Swapping out: um processo em memória principal é transferido para o disco (memória secundaria).
Swapping in: Caso o processo precise ser executado novamente,
então ele é novamente carregado para a memória principal.
Esta operação pode até causar o swap out de um outro programa.
O processo de swapping visa estender a memória principal, criando uma área de manobra para o sistema operacional. Melhorando o processo de desfragmentação, permitindo a carga de arquivos e processos pesados, maior compartilhamento da memória. A grande dificuldade é que o processo de swapping out e swapping in, levam muito tempo pois dependem de E/S. 3.3- Paginação A paginação permite que o programa possa ser espalhado por áreas não contíguas de memória. Com isso, o espaço de endereçamento lógico de um processo é dividido em páginas lógicas de tamanho fixo e a memória física é dividida em páginas com tamanho fixo, com tamanho igual ao da página lógica. Nisso, o programa é carregado página a página, cada página lógica ocupa uma página física e as páginas físicas não são necessariamente contíguas. O endereço lógico é inicialmente dividido em duas partes : um número de página lógica (usado como índice no acesso a tabela de páginas, de forma a obter o número da página física correspondente) e um deslocamento dentro da página. Não existe fragmentação externa, porém existe fragmentação interna (Ex: um programa que ocupe 201kb, o tamanho de página é de 4 kb, serão alocadas 51 páginas resultando uma fragmentação interna de 3kb). Além da localização a tabela de páginas armazena também o bit de validade, (1 ou TRUE) se a página está na memória (0 ou FALSE) se a página não está na memória. E a transferência das páginas de processo podem ser transferidas para a memória por demanda, levando apenas o que é necessário para a execução do programa ou por paginação antecipada, onde o sistema tenta prever as páginas que serão necessárias à execução do programa. Abaixo um exemplo de páginas constantemente referenciadas: 3.4- Segmentação: Técnica de gerência de memória onde programas são divididos em segmentos de tamanhos variados cada um com seu próprio espaço de endereçamento. A principal diferença entre a paginação e a segmentação é a alocação da memória de maneira não fixa, a alocação depende da lógica do programa. O mapeamento é feito através das tabelas de mapeamento de segmentos e os endereços são compostos pelo número do segmento e um deslocamento dentro do segmento. Cada entrada na tabela mantém o endereço físico do segmento, o tamanho do segmento, se ele está ou não na memória e sua proteção. Para isso ocorrer sem problemas, o sistema operacional mantém uma tabela com as áreas livres e ocupadas da memória e somente segmentos referenciados são transferidos para a memória principal. Nesse modelo diferentemente da Paginação, ocorre fragmentação externa. Abaixo um exemplo de Segmentação: 3.4.1- Paginação com Segmentação
Se os segmentos são grandes, não dá para mantê-los na memória em
sua totalidade. Gerando a ideia de paginar os segmentos só deixando na memória as páginas realmente necessárias a cada segmento. Um exemplo de SO que usa esse conceito é o MULTICS que foi o primeiro sistema com suporte a segmentos paginados. E como funciona? Simples, cada segmento é dividido fisicamente em páginas e o endereço é formado pelo número do segmento, número da página dentro desse segmento e o deslocamento dentro dessa página. Abaixo um exemplo de funcionamento de Paginação com Segmentação no MULTICS: Qual é a diferença entre a paginação e a segmentação?
A principal diferença entre a paginação e a segmentação é a alocação
da memória de maneira não fixa, a alocação depende da lógica do programa. O mapeamento é feito através das tabelas de mapeamento de segmentos e os endereços são compostos pelo número do segmento e um deslocamento dentro do segmento. 3.5- Memória Virtual A Memória Virtual é um espaço variável e reservado no disco rígido. Este espaço é reservado no momento em que é feito a instalação do Sistema Operacional, seja ele Windows, Linux, e etc. Quando o Sistema Operacional notar que a Memória RAM não tem mais espaço de execução, o sistema vai passar a executar os seus programas na Memória Virtual. Pode-se dizer que, a memória virtual é como se fosse uma reserva da Memória RAM, ou seja, se a Memória RAM estiver cheia, é utilizado a memória Virtual. Algumas características:
Quando a Memória Virtual é utilizada, o sistema fica extremamente
lento (isto porque o HD é considerado um tipo de memória lenta – utiliza componentes mecânicos); A Memória Virtual pode ser chamada também de: Page-file, paginação, memória paginada, swap ou memória de troca. Embora o trabalho de computação fosse realizado pelo sistema, o trabalho de dividir o programa em pedaços tinha de ser realizado pelo programador. Um meio de permitir que o próprio sistema operacional faça esse trabalho do programador é denominado Memória Virtual, método inventado por Fotheringham em 1961. Na gestão de memória convencional páginas ou segmentos (unidades) de um programa são todos carregados para MP antes de sua execução. Devido a localidade, um programa só precisa de algumas dessas unidades em um dado momento. É possível gerir a memória de forma que só unidades necessárias em um dado momento estejam na MP. Memória física pode ser melhor aproveitada, sendo possível: Executar um programa maior que a MP. Executar vários programas “ao mesmo tempo” que somados são maiores que a MP. Neste caso, a CPU gera endereços para espaço de endereçamento lógico maior que tamanho da MP física (daí o nome virtual). Para efeitos de gestão da Memória Virtual, o SO aplica regras:
Quando processo inicia não são carregadas todas suas unidades
para MP As tabelas de conversão de endereços indicam unidades que estão na MP (bit de validade). Quando necessário, o sistema gera um page-fault e manda buscar página do disco. Carregadas por demanda. O processo perde o processador Processo só retorna para fila de pronto quando unidade estiver disponível na MP Se MP ficar cheia, novas unidades são colocadas no lugar das menos recentemente usadas (LRU) Essa técnica tem os seguintes custos associados: Miss-penalty alto, pois unidades têm que ser buscadas do disco Aumenta número de trocas de contexto por causa de page-faults e de eventos a serem tratados (evento gerado quando a unidade foi trazida) A idéia da memória virtual é que o tamanho combinado do programa e dos dados podem exceder o tamanho da memória física disponível. O SO mantém essas partes do programa actualmente em uso na memória principal e o restante em disco. A memória virtual pode trabalhar em um sistema multiprogramável, com pedaços de programas na memória simultaneamente. Enquanto um programa está esperando parte dele próprio ser trazido para a memória, ele fica esperando a E/S e não pode executar. Dessa forma a CPU pode ser dada a outro processo, como em qualquer outro SO. O algorítmo de substituição de páginas (swapping) são políticas definidas para escolher qual(is) página(s) da memória dará lugar a página que foi solicitada e que precisa ser carregada. Isto é necessário quando não há espaço disponível para armazenar a nova página. Um facto que deve ser observado é que a página enquanto carregada sofreu actualizações e precisa ser actualizada no disco. Se ela não foi actualizada não há esta necessidade. As políticas de substituição devem ser empregadas em sistemas que fazem uso de memória virtual paginada com o objectivo de melhorar o desempenho do sistema computacional. Os algorítmos podem ser divididos em: Algorítmos com espaço fixo; Algorítmos de espaço variável. A diferença está em trabalhar com um endereço fixo de memória e a capacidade de redimensionar o tamanho da memória alocada dinamicamente. Vantagens
Executar programas maiores que o tamanho da memória.
Executar programas carregados parcialmente. Permitir mais do que um programa ao mesmo tempo. Permitir código independente de posição. Libertar programadores da alocação de memória. Permitir partilha TRASHING Problema que pode ocorrer na gestão de memória virtual é o Trashing. Trashing vem de Trash (lixo) e indica que nada de produtivo está sendo feito. Ocorre quando sistema fica maior parte do tempo trocando páginas e processador não consegue executar nenhum processo. Ocorre quando muitos processos estão activos e MP é proporcionalmente pequena para acomodar as unidades. Assim, quando processo ganha CPU ele manda trazer suas unidades e volta a dormir, quando essas unidades são trazidas. A gestão de memória apaga unidades de outro processo por causa da falta de espaço na memória. Quando for a vez desse outro, suas páginas já não estão mais na memória, e assim por diante… Acima de um certo número de processos activos o desempenho da máquina começa a diminuir. Este número é bastante dinâmico e depende: Da arquitetura da máquina Do tamanho da MP Do número de processos activos Do tipo de processos que estão activos (io-bound, cpu-bound) Próxima aula: Capítulo 5- Sistemas de Arquivos
5.1 Conceitos 5.2 Métodos de acesso 5.3 Estrutura de directório