Baixe o app para aproveitar ainda mais
Prévia do material em texto
SISTEMAS OPERACIONAIS Cleverson Lopes Ledur Gerência de memória Objetivos de aprendizagem Ao final deste texto, você deve apresentar os seguintes aprendizados: � Definir a hierarquia de armazenamento de um computador. � Identificar os modos de gerenciamento de memória e suas características. � Reconhecer o funcionamento da memória virtual. Introdução Quando um processo é executado num computador, ele precisa de tempo de CPU, mas precisa também de memória. Quando os processos são executados, precisam ocupar espaço na memória para que o computador possa ler e carregá-los rapidamente. No entanto, em comparação com nossos discos rígidos, a memória volátil é pequena. Então, para nos dar mais memória do que temos fisicamente, usamos algo chamado memória virtual. Trata-se de uma combinação de espaço no disco rígido e na RAM, que funciona como a memória que os processos podem usar. Quando executamos um processo, pegamos os dados do programa em partes que chamamos de páginas. Armazenamos essas páginas na memória virtual. Se quisermos ler e executar essas páginas, elas devem ser enviadas para a memória física, ou RAM. Este é apenas um dos conceitos que temos sobre gerenciamento de memória em sistemas operacionais. É importante o conhecimento desses processos para entender como o sistema operacional realiza a abstração das complexidades. Neste capítulo, você vai conhecer outros conceitos sobre geren- ciamento de memória e, ao final, vai definir a hierarquia de armazena- mento de um computador; vai identificar os modos de gerenciamento de memória e suas características e vai reconhecer o funcionamento da memória virtual. Hierarquia de armazenamento A hierarquia de memória organiza o armazenamento do computador com base no tempo de resposta. Como o tempo de resposta está relacionado à complexidade e à capacidade, os níveis também podem ser diferenciados por suas tecnologias de desempenho e controle. A hierarquia de memória afeta o desempenho no projeto de arquitetura do computador, nas previsões de algoritmo e nas construções de programação de nível inferior, que envolvem a localidade de referência (TANENBAUM; BOS, 2014). O design para alto desempenho requer considerar as restrições da hierarquia de memória, ou seja, o tamanho e os recursos de cada componente. Cada um dos vários componentes pode ser visto como parte de uma hierarquia de memórias (m1, m2, ..., mn) em que cada membro mi é tipicamente menor e mais rápido que o próximo maior membro mi + 1 da hierarquia. Para limitar a espera por níveis mais altos, um nível mais baixo responderá preenchendo um buffer e, em seguida, sinalizando para ativar a transferência. Existem quatro níveis principais de armazenamento. � Interno — registradores e cache do processador. � Principal — a RAM do sistema e as placas controladoras. � Armazenamento em massa on-line — armazenamento secundário. � Armazenamento off-line — armazenamento terciário e off-line. Essa é uma estruturação geral da hierarquia de memória. Muitas outras estruturas são úteis. Por exemplo, um algoritmo de paginação pode ser con- siderado como um nível de memória virtual ao projetar uma arquitetura de computador e pode-se incluir um nível de armazenamento nearline entre o armazenamento on-line e off-line. Veja na Figura 1 os níveis de armazenamento dentro de um sistema com- putacional. Na parte superior, temos os registradores da CPU, seguidos pelos níveis de cache. Note que, quanto mais próximo da parte superior, temos o armazenamento que ocorre em tempo de processamento ou quase. Descendo, temos um distanciamento do processador, aparecendo a memória RAM e, após, os dispositivos de armazenamentos e as fontes de entrada/saída. Gerência de memória2 Figura 1. Níveis de armazenamento no sistema operacional. Fonte: Duarte (2012, documento on-line). Áreas de armazenamento permanente Áreas de armazenamento temporário Teclado ROM/ BIOS Memória física Nível 2 Nível 1 Cache Registra- dores da CPU Memória virtual Discos removíveis Disco rígido Armaze- namento rede/ internet Mouse Mídia removível Fontes remotas Outras fontes Scanner/ câmera/ microfone/ vídeo RAM Tipos de dispositivos de armazenamento Fontes de entrada Modos de gerenciamento de memória O gerenciamento de memória é a funcionalidade de um sistema operacional que manipula ou gerencia a memória principal e move os processos de um lado para outro, entre a memória principal e o disco durante a execução. O gerenciamento de memória monitora toda e qualquer localização de memória, independentemente de ela estar alocada a algum processo ou estar livre. Ele verifica quanta memória deve ser alocada para processos. Decide qual processo terá memória a que horas. Ele rastreia sempre que alguma memória é liberada ou não alocada e, correspondentemente, atualiza o status (TANENBAUM; BOS, 2014). Espaço de endereço do processo O espaço de endereço do processo é o conjunto de endereços lógicos a que um processo faz referência em seu código. Por exemplo, quando o endereçamento 3Gerência de memória de 32 bits está em uso, os endereços podem variar de 0 a 0x7fffffff; ou seja, 231 números possíveis, para um tamanho teórico total de 2 gigabytes. O sistema operacional cuida do mapeamento dos endereços lógicos para os endereços físicos no momento da alocação de memória para o programa. Existem três tipos de endereços usados em um programa, antes e depois da memória ser alocada � Endereços simbólicos — os endereços usados em um código-fonte. Os nomes das variáveis, constantes e rótulos de instrução são os elementos básicos do espaço de endereço simbólico. � Endereços relativos — no momento da compilação, um compilador converte endereços simbólicos em endereços relativos. � Endereços físicos — o carregador gera esses endereços no momento em que um programa é carregado na memória principal. Endereços virtuais e físicos são os mesmos em tempo de compilação e esquemas de ligação de endereço de tempo de carregamento. Endereços virtuais e físicos diferem no esquema de vinculação de endereço de tempo de execução. O conjunto de todos os endereços lógicos gerados por um programa é referido como um espaço de endereçamento lógico. O conjunto de todos os endereços físicos correspondentes a esses endereços lógicos é chamado de espaço de endereço físico. O mapeamento de tempo de execução do endereço virtual para o físico é feito pela unidade de gerenciamento de memória (MMU), que é um dispositivo de hardware. A MMU usa o mecanismo a seguir para converter o endereço virtual em endereço físico (TANENBAUM; BOS, 2014). O valor no registro base é adicionado a cada endereço gerado por um processo do usuário, que é tratado como offset no momento em que é enviado para a memória. Por exemplo, se o valor do registro de base for 10000, uma tentativa do usuário de usar o local de endereço 100 será realocada dinamica- mente para o local 10100. O programa do usuário lida com endereços virtuais; nunca vê os endereços físicos reais. Carregamento estático versus dinâmico A escolha entre carregamento estático ou dinâmico deve ser feita no momento em que o programa de computador está sendo desenvolvido. Se você tiver que carregar seu programa estaticamente, então, no momento da compilação, os programas completos serão compilados e vinculados sem deixar nenhum pro- Gerência de memória4 grama externo ou dependência de módulo. O vinculador combina o programa objeto com outros módulos de objetos necessários em um programa absoluto, que também inclui endereços lógicos. Se você estiver escrevendo um programa carregado dinamicamente, então seu compilador irá compilar o programa para todos os módulos que você deseja incluir dinamicamente. Apenas referências serão fornecidas e o resto do trabalho será feito no momento da execução. No momento do carregamento, com carregamento estático, o programa absoluto (e dados) é carregado na memória para que a execução sejainiciada. Se você estiver usando o carregamento dinâmico, as rotinas dinâmicas da biblioteca serão armazenadas em um disco no formato relocável e serão carregadas na memória somente quando forem necessárias ao programa. Ligação estática versus dinâmica Quando é usada a vinculação estática, o vinculador combina todos os outros módulos necessários a um programa em um único programa executável, para evitar qualquer dependência de tempo de execução. Quando a vinculação dinâmica é usada, não é necessário vincular o módulo ou biblioteca real ao programa, mas uma referência ao módulo dinâmico é fornecida no momento da compilação e vinculação. Bibliotecas de vínculo dinâmico (DLL), no Windows, e objetos compartilhados, no Unix, são bons exemplos de bibliotecas dinâmicas. Swapping Swapping é um mecanismo em que um processo pode ser trocado temporaria- mente da memória principal (ou movido) para o armazenamento secundário (disco) e disponibilizar essa memória para outros processos. Posteriormente, o sistema troca o processo do armazenamento secundário para a memória principal. Embora o desempenho seja geralmente afetado pelo processo de troca, o swapping ajuda na execução de múltiplos e grandes processos em paralelo. Essa é a razão pela qual também é reconhecido como uma técnica de com- pactação de memória. O tempo total gasto pelo processo de troca inclui o tempo necessário para mover todo o processo para um disco secundário e depois para copiar o processo de volta à memória, bem como o tempo que o processo leva para recuperar a memória principal. 5Gerência de memória Vamos supor que o processo do usuário seja de tamanho 5.120 Kb em um disco rígido padrão e a troca ocorra a uma taxa de transferência de dados em torno de 1 Mb por segundo. A transferência real do processo de 1.000 K da memória levará 5.120 Kb / 1.024 Kb por segundo; = 5 segundos = 5.000 milissegundos Agora considerando o tempo de entrada e saída, ele levará 7.000 milisse- gundos completos, além de outro overhead, em que o processo compete para recuperar a memória principal. Alocação de memória A memória principal geralmente tem duas partições: � Baixa memória — o sistema operacional reside nesta memória. � Alta memória — os processos do usuário são mantidos em alta memória. O sistema operacional usa o seguinte mecanismo de alocação de memória: � Alocação de partição única — nesse tipo de alocação, o esquema de registro de relocação é usado para proteger os processos do usuário uns dos outros e de alterar o código e os dados do sistema operacional. O registro de realocação contém o valor do menor endereço físico, enquanto o registro de limite contém o intervalo de endereços lógicos. Cada endereço lógico deve ser menor que o registrador de limite. � Alocação de múltiplas partições — nesse tipo de alocação, a memória principal é dividida em várias partições de tamanho fixo, onde cada partição deve conter apenas um processo. Quando uma partição está livre, um processo é selecionado da fila de entrada e é carregado na partição livre. Quando o processo termina, a partição fica disponível para outro processo. Conforme a Figura 2, temos basicamente dois tipos de alocação, a contígua e a não contígua. A alocação contígua consiste em armazenar um arquivo em blocos sequencialmente dispostos, permitindo ao sistema localizar um arquivo por meio do endereço do primeiro bloco e da sua extensão em blocos. Essa, então, é dividida em simples e particionada, podendo ser estática ou dinâmica. A alocação contígua realiza o uso ineficiente de memória (fragmentação interna Gerência de memória6 e externa) devido à exigência de que toda memória alocada a um processo deveria ser contínua. A solução é o uso de alocação não contígua, ou seja, utilizar sistemas de gestão de memória que permitam a alocação de memória física não contínua aos processos. Figura 2. Tipos de alocação de memória. Fragmentação Como os processos são carregados e removidos da memória, o espaço de memória livre é dividido em pequenos pedaços. Às vezes, não se consegue alocar processos para blocos de memória, considerando seu tamanho pequeno, e os blocos de memória permanecem sem uso. Esse problema é conhecido como fragmentação. A fragmentação pode ser de dois tipos: � Fragmentação externa — o espaço total de memória é suficiente para satisfazer uma solicitação ou para residir em um processo, mas não é contíguo e, portanto, não pode ser usado. A fragmentação externa pode ser reduzida pela compactação ou pelo conteúdo da memória aleatória para colocar toda a memória livre em um único bloco grande. Para tornar a compactação viável, a realocação deve ser dinâmica. � Fragmentação interna — o bloco de memória atribuído ao processo é maior e alguma parte da memória é deixada sem uso, já que não pode ser usada por outro processo. A fragmentação interna pode ser reduzida atribuindo efetivamente a menor partição, mas grande o suficiente para o processo. 7Gerência de memória Paginação Um computador pode endereçar mais memória do que a quantidade fisicamente instalada no sistema. Essa memória extra é, na verdade, chamada de memória virtual e é uma seção de um disco rígido que é configurado para emular a RAM do computador. A técnica de paginação desempenha um papel importante na implementação da memória virtual. Paginação é uma técnica de gerenciamento de memória na qual o espaço de endereço do processo é dividido em blocos do mesmo tamanho, chamados de páginas (o tamanho é a potência de 2, entre 512 bytes e 8192 bytes). O tamanho do processo é medido no número de páginas. Da mesma forma, a memória principal é dividida em pequenos blocos de tamanho fixo de memória (física) chamados quadros. O tamanho de um quadro é mantido o mesmo que o de uma página para otimizar a utilização da memória principal e evitar fragmentação externa. Quando o sistema aloca um quadro a qualquer página, ele converte esse endereço lógico em um endereço físico e cria uma entrada na tabela de páginas, a ser usada durante a execução do programa. Quando um processo deve ser executado, suas páginas correspondentes são carregadas em qualquer quadro de memória disponível. Suponha que você tenha um programa de 8 Kb, mas sua memória pode acomodar apenas 5 Kb em um determinado ponto no tempo. Então, o conceito de paginação entrará em cena. Quando um computador fica sem RAM, o sistema operacional mo- verá páginas de memória ociosas ou indesejadas para a memória secundária, liberando memória RAM para outros processos e trazendo de volta quando necessário ao programa. Este processo continua durante toda a execução do programa, onde o sistema operacional continua removendo as páginas ociosas da memória principal, as grava na memória secundária e as traz de volta quando requerido pelo programa. A paginação reduz a fragmentação externa, mas ainda sofre com a frag- mentação interna. Ela também é simples de implementar e reconhecida como uma técnica eficiente de gerenciamento de memória. Devido ao tamanho igual das páginas e frames, a troca torna-se muito fácil. No entanto, a tabela de páginas requer espaço extra na memória. Portanto, pode não ser boa solução para um sistema com pouca memória RAM. Gerência de memória8 Segmentação A segmentação é uma técnica de gerenciamento de memória na qual cada tarefa é dividida em vários segmentos de tamanhos diferentes, um para cada módulo que contém partes que executam funções relacionadas. Na verdade, cada segmento é um espaço de endereço lógico diferente no programa. Quando um processo deve ser executado, a correspondente segmentação é carregada na memória não contígua, embora cada segmento seja carregado em um bloco contíguo de memória disponível. O gerenciamento de memória de segmentação funciona de maneira muito semelhante à paginação, mas aqui os segmentos são de comprimento variável, ao passo que, na paginação, são de tamanho fixo. Um segmento de programa contém a funçãoprincipal do programa, funções de utilitário, estruturas de dados e assim por diante. O sistema operacional mantém uma tabela de mapa de segmento para cada processo e uma lista de blocos de memória livre junto com números de segmento, seu tamanho e localizações de memória correspondentes na memória principal. Para cada segmento, a tabela armazena o endereço inicial do segmento e o comprimento do segmento. Uma referência a um local da memória inclui um valor que identifica um segmento e um deslocamento. Memória virtual A memória virtual (virtual storage) é uma técnica de gerenciamento de memória que fornece uma “abstração idealizada dos recursos de armazenamento que estão realmente disponíveis em uma determinada máquina” que “cria a ilusão, para os usuários, de uma memória muito grande (principal)”. Usando uma combinação de hardware e software, o sistema operacional do computador mapeia endereços de memória usados por um programa, cha- mados endereços virtuais, em endereços físicos na memória do computador. O armazenamento principal, conforme visto por um processo ou tarefa, aparece como um espaço de endereço contíguo ou uma coleção de segmentos contíguos. O sistema operacional gerencia espaços de endereço virtual e a atribuição de memória real à memória virtual. O hardware de tradução de endereços na CPU, geralmente chamado de unidade de gerenciamento de memória ou MMU, converte automaticamente os endereços virtuais em endereços físicos. O software dentro do sistema operacional pode estender esses recursos para fornecer um espaço de endereço virtual que pode exceder a capacidade da 9Gerência de memória memória real e, portanto, fazer referência a mais memória do que a que está fisicamente presente no computador. Os principais benefícios da memória virtual incluem liberar os aplicativos de ter que gerenciar um espaço de memória compartilhada, aumentar a segu- rança devido ao isolamento de memória e ser capaz de conceitualmente usar mais memória do que pode estar fisicamente disponível se usada a técnica de paginação. Implementação da memória virtual Sabemos que a memória virtual é uma técnica implementada usando hardware e software. Ela mapeia endereços de memória usados por um programa, cha- mados endereços virtuais, em endereços físicos na memória do computador. Todas as referências de memória dentro de um processo são endereços lógicos, que são traduzidos dinamicamente em endereços físicos em tempo de execução. Isso significa que um processo pode ser trocado para dentro e para fora da memória principal, de modo que ocupe lugares diferentes na memória principal em momentos diferentes durante o curso da execução. Um processo pode ser dividido em várias partes e essas peças não precisam estar continuamente localizadas na memória principal durante a execução. A combinação de conversão de endereços de tempo de execução dinâmica e o uso de tabela de páginas ou segmentos permite isso. Se essas características estiverem presentes, não é necessário que todas as páginas ou segmentos estejam presentes na memória principal durante a execução. Isso significa que as páginas necessárias precisam ser carregadas na memória sempre que requeridas. A memória virtual é implementada usando paginação por demanda ou segmentação por demanda. � Paginação por demanda — o processo de carregar a página na memória sempre que ocorrer uma falha de página é conhecido como paginação por demanda. Se a CPU tentar referenciar uma página que não está atualmente disponível na memória principal, ela gerará uma interrupção, indicando a falha de acesso à memória. O sistema operacional coloca o processo interrompido em um estado de bloqueio. Para que a execução prossiga, o sistema operacional deve trazer a página necessária para a memória e ele irá procurá-la no espaço de endereço lógico. Então, a página necessária será trazida, do espaço de endereço lógico para o espaço de endereço físico. Os algoritmos de substituição de página são Gerência de memória10 usados para a tomada de decisão de substituir a página no espaço de endereço físico. Ao fim, a tabela de páginas será atualizada de acordo e o sinal será enviado para a CPU, para continuar a execução do programa, e colocará o processo de volta ao estado pronto. � Tempo de serviço de falha de página — o tempo gasto para atender a falha de página é chamado de tempo de serviço de falha de página. O tempo de serviço de falha de página inclui o tempo gasto para executar todas as seis etapas acima. Algoritmos de substituição de páginas Em sistemas operacionais que usam paginação para gerenciamento de me- mória, o algoritmo de substituição de página é necessário para decidir qual página precisa ser substituída quando uma nova página chegar. Sempre que uma nova página é referenciada e não está presente na memória, ocorre falha de página e o sistema operacional substitui uma das páginas existentes pela página recém-necessária. Diferentes algoritmos de substituição de página sugerem diferentes manei- ras de decidir qual página substituir. O alvo de todos os algoritmos é reduzir o número de falhas de página. � First-in-first-out (FIFO) — com o algoritmo FIFO, o sistema operacio- nal mantém uma fila para rastrear todas as páginas na memória, com a chegada mais recente na parte de trás (cauda da fila) e a chegada mais antiga na frente (cabeça da fila). Quando o sistema precisa de espaço, uma página será substituída. Com o FIFO, a página na frente da fila (a página mais antiga) é selecionada para substituição. No entanto, FIFO é conhecido por sofrer de um problema conhecido como anomalia de Belady, que ocorre quando o aumento do número de quadros de página resulta em um aumento no número de falhas de página para um determinado padrão de acesso à memória. � Menos recentemente usado (LRU) — o algoritmo de substituição de páginas LRU controla o uso de páginas em uma janela de tempo definida. Quando é hora de substituir uma página, ela substitui a página menos usada recentemente. � Substituição ideal da página — nesse algoritmo, as páginas são subs- tituídas pelo critério do que não seria usado durante o maior período de tempo no futuro. 11Gerência de memória No Linux (Ubuntu), você consegue verificar como está o uso de memória do compu- tador por meio do System Monitor (Figura 3). Figura 3. System Monitor. Note os indicadores do meio da tela, onde temos as informações Memory and Swap History. Trata-se de como está o consumo de memória RAM e também do uso do swap. Nesta imagem, você pode verificar que, dos 7.4 GiB disponíveis, estamos utilizando 6.8 GiB. Como o uso da memória está quase no limite, o sistema operacional gerencia a troca (swapping) de alguns itens para a partição swap. No caso desse computador, temos uma partição de 22 GiB reservada para swapping. Logo, o sistema operacional já moveu alguns itens, totalizando 8,7 GiB de uso no swap. Gerência de memória12 DURTE, D. O que é memória virtual. Pura Info, 22 nov. 2012. Disponível em: <https:// www.purainfo.com.br/artigos/o-que-e-memoria-virtual/>. Acesso em: 9 dez. 2018. TANENBAUM, A. S.; BOS, H. Modern operating system. London: Pearson Education, 2014. Leituras recomendadas ARPACI-DUSSEAU, R. H.; ARPACI-DUSSEAU, A. C. Operating systems: three easy pieces. Dusseau Books, 2014. GERALDI, L. M. A. Elucidando os sistemas operacionais: um estudo sobre seus conceitos. Clube de Autores, 2009. SILBERSCHATZ, A.; GALVIN, P. B.; GAGNE, G. Operating system concepts. New Jersey: Wiley, 2013. SILBERSCHATZ, A.; GALVIN, P. B.; GAGNE, G. Sistemas operacionais com Java. 7. ed. São Paulo: Elsevier Brasil, 2008. TANENBAUM, A. S. Sistemas operacionais modernos. São Paulo: Pearson Education do Brasil, 2009. 13Gerência de memória Conteúdo:
Compartilhar