Gerenciamento de Memória
Conceitos Fundamentais e Suporte de Hardware
Alocação de Memória Contígua
Permuta de Processos (Swapping)
Segmentação
Registradores Base/Limite
Esses registradores tem como função delimitar a área de acesso a memoria logica do usuário onde o CPU através de uma verificação do processo verifica se o endereço pelo qual deseja acessar esta entre a base e o limite se não estiver ocorre uma interceptação (erro de endereçamento)
Endereçamento Lógico/Físico
O CPU gera um endereço de lógico também conhecido como virtual adress que faz referência a um endereço fisico da memória onde a unidade de memória faz a tradução deste endereçamento
Vinculação de Endereços
As variáveis de um código fonte são simbólicas a nivel de usuário, onde o processo de vinculação faz com que essas variáveis sejam vinculadas pelo compilador a endereços lógicos gerados pelo CPU, que através do linker ou carregador vincula esses endereços lógicos aos endereços absolutos ou seja o endereço da memória física
Vinculação de instruções e dados a endereços de memória
A vinculação das instruções e dados a endereços de memória podem acontecer durante três estágios diferentes, sendo eles: durante a compilação do programa, durante o carregamento do programa ou durante a execução do programa
Management Memory Unit (MMU)
A unidade de gerenciamento de memória é o hardware responsável por traduzir em tempo de execução os endereços lógicos para endereços físicos
Carga Dinâmica
A carga dinâmica consiste em carregar programas apenas quando são chamados e somente os programas principais são chamados inicialmete, é útil quando existem grandes quantidades de código que são executados poucas vezes
Vinculação Dinâmica
A vinculação dinâmica é referência à memoria absoluta durante a execução de um programa, pois o endereço lógico é vinculado ao físico durante a o tempo de execução.
Alocação Contígua
Existe um processo de proteção da memória na alocação contígua onde o processo é impedido de acessar a memória da qual ele não possui. Registradores de relocação (RR) contém o valor do menor endereço físico e o Registrador limite (RL) contém intervalo do valor limite onde cada endereço lógico deve ser menor o valor do registrador, então o processo de alocação consiste em uma verficação onde o valor lógico deve ser menor que o registrador limite e caso seja verdadeira a verificação, o valor logico é somado com o registrador de relocação e então o endereço físico é definido.
Alocação com partições multiplas
Existem dois tipos de alocação com partições multiplas: as partições de tamanho fixo e as partições de tamnho variável, onde as de tamanho variável são mais eficientes. O sistema operacional mantém a lista de processos prontos e a lista de brechas (holes), brechas de tamanhos diferentes são esplalhadas por toda a partição e os processos prontos se alocam nas brechas onde tem tamanho suficiente para se alocarem.
Alocação Dinâmica
First-fit
Best-fit
Worst-fit
Aloca o processo na primeira brecha onde ele puder ser alocado
Percorre a pilha procurando a brecha mais pequena possível onde o processo possa ser alocado
Percorre a pilha procurando a maior brecha possível onde o processo posso ser alocado
O Swapping é o processo de troca entre a memória física e o disco também chamado de Backing store onde acontece um swapped out quando um processo com baixa prioridade deixa de ser armazenado na memória principal e é armazenado no disco, ou swapped in o processo é requisitado por algum programa e sua prioridade aumenta então o processo deixa de ser armazenado no disco e passa a ser armazenado na memória física, os SO atuais não fazem uso do Swapping por motivos de I/O pois um processo errado pode executar uma operação de I/O, somente versões modificados do Swapping são encontradas em alguns sitemas, onde ele fica desabilitado e somente é habilitado quando a memória esta extremamente cheia
Visão Lógica da Segmentação
Durante a construção de um programa a visão do programador é diferente da memória física real de um computador, onde no programa o programador tem blocos divididos, como bibliotecas, métodos, funções, etc. O processo de segmentação visa mapear a visão lógica do programador na memória física do computador, onde o programador define os segmentos de um programa pelo nome e define um deslocamento para este segmento, não se importando com o endereço físico deste segmento. Segmentos de tamanho variável compõem o endereçamento lógico
Arquitetura da Segmentação
O endereço lógico da segmentação consiste em dois valores o numero da segmentação e o numero do deslocamento da segmentação
Tabela de Segmentos
Mapeia os endereços bidimencionais em endereços unidimencionais onde cada endereço contém uma base e o limite, onde a base indica o endereço físico do inicio do segmento na memoria e o limite especifica o tamanho do segmento
Segment-table base register (STBR)
Aponta para o local da tabela de
segmentos na memória
Segment-table length register (STLR)
Indica o número de segmentos usados pelo programa onde o número de segmento "S" é legal se S < STLR
Cada processo possui sua própria tabela de segmentos
Proteção
Cada tabela de segmento tem um bit de validação onde se for igual a 0 o segmento é invalido, também existem outros bits de validação como os bits de privilégios.
Tamanho dos Segmentos
Como o tamanho dos segmentos são variáveis existem os problemas de alocação dinâmica como: first-fit, next-fit, best-fit e worst-fit; partições de tamanhos variáveis e o problema de fragmentação externa
Paginação
Esquema de tradução de Endereços
Fragmentação na Paginação
Espaços de Endereçamento
É uma técnica de gerenciamento de memória parecida com o modelo de segmentação, segue o modelo de processos não-contíguos evitando fragmentação externa, pedaços de memória de tamanhos variados, ela divide a memoria física em blocos de tamanho fixo chamos de quadros ou frames, seu tamanho é potencia de 2 facilitando a composição da memória lógica, e divide a memória lógica em blocos de mesmo tamanho chamados de páginas, quadros e páginas são sempre do mesmo tamanho. O SO precisa manter controle sobre todos os quadros livres (lista). Para executar um programa de N páginas, precisa encontrar N quadros livres e carregar o programa, durante o carregamento do processo na memória, configura a tabela de páginas (page table) para o processo. A Tabela de páginas, uma por processo, é usada para, em tempo de execução, traduzir endereços lógicos para endereços físicos. O Armazenamento de retaguarda (swap) também dividido em páginas, uma Página/Quadro pode apresentar fragmentação interna (pequena) Assim, como na abordagem por segmentação, é preciso resolver o problema de onde armazenar as tabelas de páginas
O endereço gerado pela CPU é dividido em número de página usado como índice na tabela de páginas que contém endereço base de cada página na memória física (quadro) e deslocamento na página combinado com o endereço base define o endereço físico
Não há fragmentação externa na paginação, pode haver fragmentação interna. Exemplo de cálculo de fragmentação interna: Tamanho da página = 2.048 bytes (2k), Tamanho do processo = 72.766 bytes, 35 páginas + 1.086 bytes, Fragmentação interna de 2.048 – 1.086 = 962 bytes, Apenas no último quadro. Melhor caso de fragmentação = n quadros + (1 quadro – 1 byte), Pior caso de fragmentação = n quadros + 1 byte, Em média, fragmentação = ½ quadro. Cada entrada na tabela de páginas exige memória para ser mantida, Com quadros menores a tabela aumenta de tamanho (mais linhas)
Exemplo de uma CPU de 32 bits, gera endereços lógicos de 32 bits, espaço de endereçamento lógico: 232 bytes (4GB). Uma entrada na tabela de páginas tem, tipicamente, 4 bytes (32 bits). Esse endereço físico de 32 bits pode apontar para um dos 232 quadros físicos, considerando quadros de tamanho 4KB (212). O Sistema pode endereçar 244 bytes (16 TB) de memória física. Devido ao uso de bits de controle, isso pode diminuir . A visão de processo e de memória física são diferentes na paginação. A paginação permite usar memória física maior do que pode ser endereçado pelo ponteiro de endereçamento da CPU o SO mantém uma tabela de páginas para cada processo. Há um custo maior no tempo de mudança de contexto entre processos, por implementação, cada processo pode acessar apenas sua própria memória (páginas que estão em sua própria tabela de páginas)
Implementação da tabela de páginas
Solução 1: Tabela de páginas armazenada em registradores dedicados dentro da própria CPU. Valores dos registradores são armazenados no PCB de cada processo, cada processo tem sua própria tabela de páginas, dispacher carrega esses registradores na mudança de contexto. Lógica de implementação dos registradores deve ser de alta velocidade (CI). É Viável apenas para tabelas de páginas pequenas (ex. 256 entradas).
Solução 2: Tabela de páginas mantida na memória principal, page-table base register (PTBR) aponta para a tabela de páginas, Page-table length register (PTLR) indica o tamanho da tabela. Custo: cada acesso a dado/instrução requer dois acessos a memória um para consultar a tabela de páginas e outro para o dado/instrução desejado(a). Esse problema pode ser resolvido usando um cache especial de pesquisa rápida, Translation Lookaside Buffers (TLBs) – buffer de tradução paralelo
Páginas Compartilhadas
Código compartilhado: Importante para ambientes de tempo compartilhado, uma cópia de código reentrante (read-only) compartilhada entre processos (e.g., editores de texto, compiladores, sistemas de janelas), similar a múltiplos threads compartilhando o mesmo espaço do processo. A comunicação entre processos pode ser implementada pelo compartilhamento de páginas. Um editor de texto de 150 KB de código e 50 KB de dados, para 40 usuários seriam necessários 8.000 KB, se o código (150 KB) puder ser compartilhado (código reentrante), serão necessários apenas 2150 KB