Modulo 2 - Gerenciamento de Memória

Transcrição

Modulo 2 - Gerenciamento de Memória
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
- Módulo 2 GERÊNCIA DE MEMÓRIA
A memória é um recurso importante que deve ser gerenciado com cuidado. Para isso a
maioria dos computadores tem uma hierarquização de memória, como visto na disciplina de
Arquitetura de Computadores. O trabalho do Sistema Operacional é coordenar como essas
memórias serão utilizadas. Assim, a parte do Sistema Operacional que gerencia a hierarquia de
memória é chamada Gerenciador de Memória, cujo trabalho é controlar as partes das
memórias que estão em uso ou não, alocar e desalocar memórias aos processos quando
necessário, e gerenciar a troca entre memória principal e o disco quando a memória principal é
muito pequena.
1. CONCEITOS BÁSICOS
Geralmente, os programas são armazenados em memórias secundárias, por serem meios
não-voláteis, abundantes e de baixo custo. No entanto, o processador sempre executa instruções
localizadas na memória principal, o sistema operacional deve, então, transferir dados da memória
secundária para a principal com o objetivo de reduzir a quantidade de entrada e saída – I/O.
A gerência de memória deve tentar manter na memória principal o maior número possível
de processos residentes, permitindo maximizar o compartilhamento do processador e demais
recursos computacionais.
Mesmo na ausência de espaço livre, o sistema deve permitir que novos processos sejam
aceitos e executados. Isto é realizado através de swapping, que é a transferência de processos
residentes na memória principal para a memória secundária.
O sistema também deverá permitir a execução de programas que sejam maiores que a
memória física disponível, implementando técnicas através de overlay e memória virtual. Então a
gerência de memória se preocupa em:
- Manter na memória principal o maior número de processos residentes;
- Permitir a execução de programas que sejam maiores que a memória física disponível;
- Proteger áreas de memória ocupadas por cada processo, além da área de memória
reservada ao Sistema Operacional.
2. ALOCAÇÃO DE MEMÓRIA CONTÍGUA (Monoprogramação)
A alocação contigua simples era implementada nos primeiros sistemas operacionais na qual
a memória era dividida em duas áreas, como se vê na figura 3:
- Uma para o sistema operacional
- Outra para o programa do usuário
O problema é que neste modelo algumas vezes não existia espaço suficiente na memória
para sua execução. Alguns sistemas implementavam uma proteção que impedia o programador de
obter acesso à área da memória ocupada pelo sistema operacional. Dessa forma, quando o
1
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
programa fazia referência a um endereço da memória, o Sistema Operacional verificava se o
endereço estava dentro dos limites permitidos. Estando fora, o sistema apresentava um erro.
Figura 1 – Erro
Figura 2 - Alocação contígua
As desvantagens da alocação contígua simples é que somente um usuário faz uso dos
recursos e na maior parte dos casos sempre existirá espaço de memória livre. Assim, não é
possível permitir a utilização eficiente da UCP e da memória principal, pois apenas um processo
pode utilizar esses recursos. A princípio os programas são limitados ao tamanho da memória
disponível.
Figura 3 - Alocação contígua
3. MULTIPROGRAMAÇÃO COM PARTIÇÕES FIXAS
Em geral a monoprogramação é utilizado em computadores pequenos com Sistema
Operacional bastante simples. Contudo, com freqüência é preciso permitir que vários processos
executem ao mesmo tempo.
2
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
Em sistemas de tempo compartilhado, ter vários processos na memória simultaneamente
significa que quando um processo está bloqueado outro está usando o processador. Dessa forma,
a multiprogramação aumenta a utilização da CPU.
A melhor maneira de conseguir isso é dividindo a memória em n partições que poder ser
feito manualmente quando o sistema é iniciado. Assim, quando um Job chega para ser executado
ele será colocado em uma fila para ser alocado na menor partição capaz de armazená-lo. No
entanto, pelo fato das partições serem fixas o espaço não utilizado por um job é perdido.
Figura 4 - Multiprogramação com múltiplas filas
A desvantagem de classificar os Jobs em filas de entradas separadas torna-se aparente
quando uma fila para uma partição grande está vazia e para uma partição pequena está cheia.
Uma organização alternativa é manter uma única fila de entrada.
Figura 5 - Multiprogramação com fila única
3
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
Esta organização impede o desperdício de espaço em uma partição, alocando o job na
partição de acordo com seu tamanho.
Em geral, Jobs pequenos são interativos, sendo assim é uma boa estratégia dispor de pelo
menos uma partição pequena, a qual permitirá que jobs pequenos sejam executados sem a
necessidade de alocar uma partição grande para estes Jobs.
Outra abordagem é estabelecer uma regra determinando que um job elegível para
executar, não possa ser ignorado mais do que x vezes. Toda vez que é ignorado o job ganha um
ponto. Uma vez adquirido certa quantia de pontos ele não pode ser ignorado novamente.
3.1. Técnica de Overlay
Na alocação contígua simples, todos os programas estão limitados ao tamanho da área de
memória principal disponível para o usuário. Uma solução encontrada para o problema é dividir o
programa em módulos, de forma que seja possível a execução independente de cada módulo,
utilizando uma mesma área de memória.
Considere um programa que tenha três módulos: um principal, um de cadastramento e
outro de impressão, sendo os módulos de cadastramento e de impressão independentes. A
independência do código significa que quando um módulo estiver na memória para execução, o
outro não precisa necessariamente estar presente. O módulo principal é comum aos dois módulos;
logo, deve permanecer na memória durante todo o tempo da execução do programa.
Como se vê na figura 5, a memória é insuficiente para armazenar todo o programa, que
totaliza 9kb. A técnica de overlay utiliza uma área de memória comum, onde os módulos de
cadastramento e de impressão poderão compartilhar a mesma área de memória (área de overlay).
Sempre que um dos dois módulos for referenciado pelo módulo principal, o módulo será carregado
da memória secundária para a área de overlay.
2 Kb
3 Kb
2 Kb
3 Kb
4 Kb
4 Kb
1 kb
Figura 6 – Técnica de Overlay
A definição das áreas de overlay é função do programador, através de comandos
específicos da linguagem de programação utilizada. O tamanho de uma área de overlay é
estabelecido a partir do tamanho do maior módulo.
A técnica de overlay tem a vantagem de permitir ao programador expandir os limites da
memória principal.
4
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
3.2 Realocação e Proteção
A multiprogramação introduz dois problemas que devem ser resolvidos, a relocação e
proteção. Como visto acima, jobs diferentes executarão em endereços diferentes. Quando um
programa é vinculado o linkeditor deve saber em que endereço o programa deve estar na
memória.
Suponha que uma primeira instrução seja a chamada para um procedimento no endereço
absoluto 100, produzido pelo linkeditor. Se esse programa for carregado na partição 1 esta
solicitação será executada dentro do sistema operacional. Se o programa for carregado na partição
2, isso gerará uma problema conhecido por relocação.
A solução é modificar as instruções enquanto o programa é carregado na memória. Para
realizar a relocação o linkeditor deve incluir no programa binário uma lista ou mapa de bits,
informando quais palavras do programa são endereços a serem relocados e quais instruções não
devem não devem ser relocados.
A relocação durante o carregamento não resolve o problema da proteção. Como os
programas nesse sistema utilizam endereços absolutos de memória em vez de endereços relativos
a um registrador, não há como impedir que um programa crie uma instrução que lê ou grava em
qualquer parte da memória, inclusive em área de outros usuários.
Uma solução alternativa para a relocação e proteção, é equipar a máquina com dois
registradores especiais de hardware, chamados registrador de base e registrador de limite.
Em suma, a multiprogramação implica em um problema:
- Ao mudar de partição o programa necessita ser relocado. Esta relocação implica em
correção de endereços de instruções:
- Via Software (Mapa de Correções)
- Via Hardware (Registrador de base)
As referências a posições de memórias feitas pelos processos devem ser corrigidas segundo
o deslocamento dele dentro da memória.
- Proteção: Um processo não pode invadir a memória de outros processos. Se isso acontecer
programas maliciosos poderiam interferir no funcionamento de outros programas fazendo acesso
direto à memória e interferindo na sua execução.
4. SWAPPING
Em sistemas operacionais que operam em lotes é muito efetivo utilizar partições fixas; cada
job é carregado em uma partição quando chega ao começo da fila e permanece na memória até
que termine.
Com sistemas de compartilhamento de tempo ou computadores gráficos pessoais esta
estratégia não pode ser utilizada, pois muitas vezes não há memória suficiente para armazenar
todos os processos ativos. Dessa forma, os processos em excesso são mantidos no disco e trazidos
de lá para execução dinamicamente.
O Swapping foi introduzido para contornar o problema da insuficiência de memória
principal. É aplicado à gerência de memória para programas que esperam por memória livre para
serem executados. Nesse processo são executadas duas operações:
5
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
- Swap Out: o Sistema Operacional escolhe um processo residente e o transfere para a
memória secundária.
- Swap In: ocorre um processo inverso ao swap out. O programa pode continuar sua
execução como se nada tivesse acontecido.
O algoritmo deve selecionar os processos com menos chances de serem executados. Para
tanto, geralmente são escolhidos os processos que estão no estado de espera (estado de espera
outswapped). Processos no estado de pronto também poderão ser selecionados (estado de pronto
outswapped).
Figura 7 - Swapping
Sempre que o Escalonador (CPU scheduler) decide executar um processo ele chama o
Dispatcher. O Dispatcher verifica se o processo a ser executado está residente em memória, se
não, ele remove (swap out) algum processo que esteja correntemente na memória principal e
carrega (swap in) o processo escolhido para ser executado. Após isto o contexto do processo a ser
executado é restaurado e o controle é passado ao processo que passa então a executar.
4.1. Multiprogramação com Partições Variáveis
Como visto em sistemas multiprogramados um processo não pode invadir a memória de
outro processo. No caso das partições variáveis a alocação da memória é dinâmica, ou seja, é
alterada à medida que os processos entram e saem da memória. A vantagem é a melhor utilização
da memória em relação às partições fixas; e a desvantagem é que as trocas de processos deixam
muitos espaços vazios na memória fragmentando-a. Para este problema é possível a reorganização
da memória, contudo esse processo é muito demorado.
Dois pontos devem ser considerados nas partições variáveis: a quantidade de memória que
deve ser alocada a um processo quando ele for criado. Se o processo não puder crescer então a
alocação é simples, ou seja, o Sistema Operacional aloca somente o necessário. Solução
alternativa é prevenir ou alocar uma memória extra para o seu possível crescimento. Pode-se criar
uma memória para variáveis dinâmicas que são alocadas e desalocadas (Heap), e outra (Stack)
para variáveis locais comuns e endereços de retorno.
Para que seja possível a alocação dinâmica de memória o Sistema Operacional precisa
gerenciar esse processo, usando duas formas para fazer isso:
- Gerenciamento de Memória com Mapa de Bits; e
- Gerenciamento de Memória com Listas Encadeadas.
6
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
Esses modelos serão estudados mais a frente.
Figura 8 - Multiprogramação com Partições Variáveis
O número, o tamanho e a localização das partições variam dinamicamente à medida que os
processos entram e saem da memória.
5. FRAGMENTAÇÃO
Ao longo da vida de um sistema, áreas de memória são liberadas por processos que
concluem sua execução e outras áreas são alocadas por novos processos, de forma contínua. Com
isso, podem surgir áreas livres (vazios ou buracos na memória) entre os processos, o que constitui
um problema conhecido como fragmentação externa.
Figura 9 - Fragmentação Externa
Esse problema afeta somente as estratégias de alocação que trabalham com blocos de
tamanho variável, como a alocação contígua e a alocação segmentada. A fragmentação externa é
prejudicial porque limita a capacidade de alocação de memória no sistema.
A figura 10 apresenta um sistema com alocação contígua de memória no qual ocorre
fragmentação externa. Nessa figura, observa-se que existem 68 Mb de memória livre em quatro
áreas separadas (A1 . . . A4), mas somente processos com até 28 Mb podem ser alocados (usando
7
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
a maior área livre, A4). Além disso, quanto mais fragmentada estiver a memória livre, maior o
esforço necessário para gerenciá-la: as áreas livres são mantidas em uma lista encadeada de área
de memória, que é manipulada a cada pedido de alocação ou liberação de memória.
Figura 10 - Fragmentação Externa
Pode-se enfrentar o problema da fragmentação externa de duas formas: minimizando sua
ocorrência, através de critérios de escolha das áreas a alocar, ou desfragmentando periodicamente
a memória do sistema. Para minimizar a ocorrência de fragmentação externa, cada pedido de
alocação deve ser analisado para encontrar a área de memória livre que melhor o atenda. Essa
análise pode ser feita usando um dos seguintes critérios:
- Melhor encaixe (best-fit): consiste em escolher a menor área possível que possa
atender à solicitação de alocação. Dessa forma, as áreas livres são usadas de forma otimizada,
mas eventuais resíduos (sobras) podem ser pequenos demais para ter alguma utilidade.
- Pior encaixe (worst-fit): consiste em escolher sempre a maior área livre possível, de
forma que os resíduos sejam grandes e possam ser usados em outras alocações.
- Primeiro encaixe (first-fit): consiste em escolher a primeira área livre que satisfaça o
pedido de alocação; tem como vantagem a rapidez, sobretudo se a lista de áreas livres for muito
longa.
- Próximo encaixe (next-fit): variante da anterior (first-fit) que consiste em percorrer a
lista a partir da última área alocada ou liberada, para que o uso das áreas livres seja distribuído de
forma mais homogênea no espaço de memória.
Uma forma de tratar a fragmentação externa consiste em desfragmentar a memória
periodicamente. Para tal, as áreas de memória usadas pelos processos devem ser movidas na
memória de forma a concatenar as áreas livres e assim diminuir a fragmentação. Contudo, se não
houver espaço suficiente esta movimentação vai causar um erro denominado overhead.
Ao mover um processo na memória, suas informações de alocação (registrador base ou
Tabela de segmentos) devem ser ajustadas para refletir a nova posição do processo.
Obviamente, nenhum processo pode executar durante a desfragmentação. Portanto, é
importante que esse procedimento seja executado rapidamente e com pouca freqüência, para não
interferir nas atividades normais do sistema. Como as possibilidades de movimentação de
processos podem ser muitas, a desfragmentação deve ser tratada como um problema de
otimização combinatória, cuja solução ótima pode ser difícil de calcular. As figuras abaixo ilustram
três possibilidades de desfragmentação de uma determinada situação de memória; as três
alternativas produzem o mesmo resultado, mas apresentam custos distintos.
8
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
Figura 11 - Estratégias de desfragmentação
Figura 12 - Possibilidade de desfragmentação
Além da fragmentação externa, que afeta as áreas livres entre os processos, as estratégias
de alocação de memória também podem apresentar a fragmentação interna, que pode ocorrer
dentro das áreas alocadas aos processos. A figura 9 apresenta uma situação onde ocorre esse
problema: um novo processo requisita uma área de memória com 4.900 Kbytes. Todavia, a área
livre disponível tem 5.000 Kbytes. Se for alocada exatamente a área solicitada pelo processo
(situação A), sobrará um fragmento residual com 100 Kbytes, que é praticamente inútil para o
sistema, pois é muito pequeno para acomodar novos processos. Além disso, essa área residual de
100 Kbytes deve ser incluída na lista de áreas livres, o que representa um custo de gerência
desnecessário. Outra possibilidade consiste em “arredondar” o tamanho da área solicitada pelo
processo para 5.000 Kbytes, ocupando totalmente aquela área livre (situação B). Assim, haverá
uma pequena área de 100 Kbytes no final da memória do processo, que provavelmente não será
usada por ele.
9
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
Figura 13 - Fragmentação Interna
A fragmentação interna afeta todas as formas de alocação; as alocações contíguas e
segmentada sofrem menos com esse problema, pois o nível de arredondamento das alocações
pode ser decidido caso a caso. No caso da alocação paginada, essa decisão não é possível, pois as
alocações são feitas em páginas inteiras. Assim, em um sistema com páginas de 4 Kbytes (4.096
bytes), um processo que solicite a alocação de 550.000 bytes (134,284 páginas) receberá 552.960
bytes (135 páginas), ou seja, 2.960 bytes a mais que o solicitado.
Em média, para cada processo haverá uma perda de 1/2 página de memória por
fragmentação interna. Assim, uma forma de minimizar a perda por fragmentação interna seria
usar páginas de menor tamanho (2K, 1K, 512 bytes ou ainda menos). Todavia, essa abordagem
implica em ter mais páginas por processo, o que geraria tabelas de páginas maiores e com maior
custo de gerência.
5.1. Gerenciamento de Memória com Mapa de Bits
Este tipo de gerenciamento consiste em:
- Dividir a memória em unidades de alocação (o tamanho desta unidade pode variar de
poucos bytes a vários kilobytes.
- Associar a cada unidade de alocação um bit de controle que diz se aquela unidade está
alocada ou não (0 para não alocada e 1 para alocada).
- O conjunto de todos os bits de controle é denominado Mapa de Bits.
Para alocar a memória para um processo o Sistema Operacional deve, inicialmente,
percorrer o mapa de bits em busca de uma seqüência de 0’s que represente um espaço de
memória capaz de suportar o processo, que pode ser muito demorado.
5.1.1. TAMANHO DA UNIDADE DE ALOCAÇÃO
Quanto menor a unidade de alocação, maior será o mapa de bits e maior o tempo de
procura do Sistema Operacional em busca de espaço disponível para carregar o processo.
Contudo, maior será o aproveitamento da memória.
10
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
Quanto maior a unidade de alocação, menor será o mapa de bits e menor será o tempo de
procura do Sistema Operacional em busca de espaço disponível para carregar o processo.
Contudo, menor será o aproveitamento da memória, pois na última posição sempre poderá sobrar
muito espaço da unidade de alocação.
5.2. Gerenciamento de Memória com Listas Encadeadas
Este tipo de gerenciamento consiste em:
- Manter uma lista encadeada que represente a situação da memória;
- Cada nó da lista pode representar um processo na memória ou um espaço na memória;
- Cada nó vai ter dois vizinhos, que representarão exatamente a situação da vizinhança
daquele nó na memória, ou seja:
- Se o nó representa um espaço em branco os seus vizinhos deverão representar
dois processos, pois na memória, um espaço em branco sempre é delimitado por processos;
- Se o nó representa um processo, os seus vizinhos poderão ser espaços em branco
ou processos, dependendo da situação da memória.
5.2.1. ALGORITMOS UTILIZADOS NO GERENCIAMENTO DE MEMÓRIA COM LISTAS ENCADEADAS
Firstfit: O gerenciador de memória procura na lista encadeada um nó que represente um
segmento de memória livre suficientemente grande para suportar o processo que deve ser
carregado. Então o segmento de memória é quebrado em duas partes, uma com o processo e o
que sobrar em um novo nó que representa um segmento livre.
Nextfit: Funciona como o FirstFit, contudo quando encontra um segmento de memória
apto ele guarda a posição e na próxima vez que for chamado começa a busca a partir daquele
ponto.
Bestfit: Este algoritmo vasculha a lista toda à procura de um espaço que se ajuste o mais
perfeitamente possível ao tamanho do processo. É o algoritmo que mais desperdiça memória dos
três até aqui citados.
Worst fit: Vasculha a lista à procura do maior espaço disponível, já que tomando o maior
espaço possível, o restante do espaço ainda é grande o suficiente para acomodar um novo
processo. Na verdade, a simulação mostrou que esta abordagem não leva a bons resultados.
5.3. Alocação de Espaço de Troca (swap)
Espaço de troca é o espaço ocupado no disco pelos processos que aí estão guardados, pois
foram retirados da memória devido a uma troca. Os algoritmos para gerenciar o espaço alocado
em disco para swap são os mesmos apresentados para o gerenciamento de memória. 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.
11
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
6. GERENCIAMENTO DE MEMÓRIA DO LINUX
No Linux, processos que estão em execução têm prioridade na memória, quando termina
um processo e havendo espaço na memória, ficam resíduos desse processo para uma futura volta
desse processo ser mais rápida. Os dados não são apagados imediatamente após o encerramento
da execução. Isso garante maior agilidade na execução dos processos. Caso a memória RAM
esteja lotada com processos que estão em execução, aí começa a utilização da memória SWAP
(troca) (LIMA, 2007). Daí a grande importância que o Linux dispensa a este espaço, ao ponto de
criar uma partição exclusiva para este fim.
Cada processo do Linux, em uma máquina de 32 bits, dispõe de 3GB de espaço de
endereçamento virtual para si próprio, com 1GB restante reservado para suas tabelas de páginas e
outros dados do núcleo. O 1GB do núcleo não é visível quando o processo executa no modo
usuário, mas torna-se acessível quando o processo faz uma chamada ao núcleo. O espaço de
endereçamento é gerado quando o processo é criado e sobrescrito em uma chamada ao sistema
exec1.
O espaço de endereçamento virtual é dividido em áreas ou regiões organizadas em páginas
contíguas e homogêneas. Isso quer dizer que cada área consiste de uma série de páginas
consecutivas com proteção e propriedades de paginação idênticas. O segmento de código e os
arquivos mapeados são exemplos de áreas. Pode haver vazios no espaço de endereçamento
virtual entre essas áreas. Qualquer referência à memória para um vazio resulta em uma falta de
página fatal (Page fault). O tamanho da página é fixo.
O Linux usa um esquema de paginação de três níveis que também é empregado de
maneira modificada em várias arquiteturas. Cada endereço virtual é quebrado em até quatros
campos. O campo diretório é usado como índice do diretório global, sendo que existe um privado
para cada processo. O valor encontrado é um ponteiro para um dos diretórios intermediários de
página, o qual é indexado por um campo do endereço virtual. A entrada selecionada aponta para a
tabela de página final, a indexada pelo campo página do endereço virtual. A entrada encontrada
aponta para a página requisitada. No Pentium, que usa paginação em dois níveis, cada diretório
intermediário de página tem somente uma entrada, de modo que, efetivamente, a entrada do
diretório global é quem escolhe a tabela de página a usar.
O Linux gerencia a memória usando o algoritmo companheiro, com a adição de um vetor
no qual o primeiro elemento é a cabeça de uma lista de blocos com tamanho de uma unidade. O
segundo elemento é a cabeça de uma lista de blocos com tamanho de duas unidades. O próximo
elemento aponta para blocos de quatro unidades e assim por diante. Dessa maneira qualquer
bloco de potência de dois pode ser encontrado rapidamente.
A vantagem do algoritmo do companheiro é que facilita a busca de bloco livre, se for
implementada com uma estrutura de árvore.
1
Relembrando, um processo pode ser:
Fork: Criar um novo processo;
Wait: Aguardar o término de seu filho;
Exec: Executar outro programa;
Exit:Terminar sua execução;
12
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
No entanto, esse algoritmo gera uma considerável fragmentação interna, pois, se você
deseja um bloco de 65 páginas, você tem de solicitar e obter um bloco de 128 páginas.
Figura 14 - Algoritmo do companheiro
A fragmentação é resolvida pelo Kernel com um processo de desfragmentação que junta
espaços preenchidos de memória que são categoricamente semelhantes.
Isto é feito com uma segunda alocação de memória que obtêm blocos, usando o algoritmo
companheiro, e depois os retalha (unidades menores) para gerenciar unidades menores
separadamente.
Um terceiro alocador de memória também é utilizado quando a memória solicitada precisa
ser contígua somente no espaço virtual, mas não na memória física. (TANEMBAUM, 2005)
Para a proteção existe um gerenciador de memória virtual evitando que processos no modo
Kernel e no modo User se misturem.
6.1. Comandos no Linux para Administração de Memória
Os comandos abaixo permitem a visualização e gerenciamento da memória:
Free: Mostra espaços livres e ocupados da memória RAM e SWAP.
Parâmetros:
-b Visualiza os dados em bytes
-k Visualiza os dados em kilobytes
-m Visualiza os dados em megabytes
-g Visualiza os dados em gigabytes
Como se vê na figura abaixo há 249 Mb livres de memória RAM e, portanto não há uso de
memória SWAP.
13
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
Figura 15 - Comando Free
Na linha Mem é mostrada a memória física, em -/+ buffers/cache são mostrados
somente os processos que estão em execução e quanto tem disponível, ignorando os resíduos de
outros processos e em SWAP é mostrada a área de troca usada.
Memstat: Lista todos os processos, executáveis e Libraries partilhadas que usam memória virtual.
Identifica quem está usando a memória virtual alta. De acordo com o manual do Linux, este
comando tem as seguintes opções de visualização:
-w Mostra os resultados estendidos sem truncar informações em 80 colunas
A desvantagem experimentada com o comando memstat é a quantidade de informações
que ele retorna. Por este motivo pode ser avaliada a praticidade de concatenar comandos com
filtros específicos.
Exemplo:
memstat -w | grep /var/cache
O resultado obtido mostra o consumo de memória por módulo, o nome de cada um deles e
os processos ao qual está vinculado.
PMap: Reporta o mapa de memória de um determinado processo. Este comando é específico de
um processo em particular. Ele poderá mostrar os módulos que são carregados nesse processo.
Para obter as informações deverá ser usado o comando ps para que seja visualizado o id
do processo para depois fornecê-lo como atributo do pmap.
7. NÍVEIS DE OPERAÇÃO (RUNLEVELS) NO LINUX
No Linux e outros sistemas baseados no Unix o runlevel indica o modo de operação atual
da máquina, definindo quais serviços e recursos devem permanecer ativos. O runlevel pode ser
alterado a qualquer momento pelo root, através do comando telinit (# telinit 3, # telinit 5, etc.).
No Linux os runlevels são numerados de 0 a 6, como se segue:
- Nível 0: O sistema está parado, nenhum processo é executado. Este modo entra em
ação quando desligamos o sistema via software.
- Nível 1: É chamado de single user mode é um modo de recuperação, onde temos ativa
apenas a conta de superusuário. Não é possível usar a rede nem rodar programas gráficos. Neste
modo é possível alterar as configurações do sistema, alterar as senhas dos usuários, etc.
14
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
- Níveis 2 e 3: Modo de operação normal do sistema. Nestes modos o sistema inicializa
em modo texto e depois de logado o usuário pode abrir o modo gráfico se desejar. A diferença
entre os dois é que no modo 2 (também considerado um modo de recuperação) não existe
suporte a rede.
- Nível 5: Inicialização com login em modo gráfico, default na maioria das distribuições
atualmente. O nível 4 geralmente fica vago. Na maioria das distribuições ele equivale ao modo 3,
enquanto em outras, como no Slackware, equivale ao modo de login gráfico.
- Nível 6: É reservado à reinicialização do sistema. Todos os serviços e programas são
parados e o sistema é reinicializado via software. O nível 6 difere do nível 0, onde o sistema fica
simplesmente parado, esperando ser desligado.
Existe ainda um nível especial, o nível S, que dependendo da distribuição equivale ao nível
1 ou 6.
O nível de execução atual do sistema pode ser visualizado através do comando runlevel e
modificado através dos programas init ou telinit.
Quando é executado, o runlevel lê o arquivo /var/run/utmp e adicionalmente lista o nível
de execução anterior ou a letra N em seu lugar (caso ainda não tenha ocorrido a mudança do nível
de execução do sistema).
No Debian, os diretórios /etc/rc0.d a /etc/rc6.d contém os links simbólicos para arquivos
em /etc/init.d que são acionados pelo nível de execução correspondente.
Por exemplo, o arquivo S10sysklogd em /etc/rc2.d, é um link simbólico para
/etc/init.d/sysklogd.
O Debian segue o seguinte padrão para definir se um link simbólico em /etc/rc[0-6].d
iniciará ou interromperá a execução de um serviço em /etc/init.d, que é o seguinte:
- Se um link é iniciado com a letra K (kill), quer dizer que o serviço será interrompido
naquele nível de execução. O que ele faz é executar o daemon em /etc/init.d seguido de stop.
- Se um link é iniciado com a letra S (start), quer dizer que o serviço será iniciado naquele
nível de execução (é equivalente a executar o daemon seguido de start).
Primeiro os links com a letra K são executado e depois os S. A ordem que os links são
executados dependem do valor numérico que acompanha o link, por exemplo, os seguintes
arquivos são executados em seqüência:
S10sysklogd
S12kerneld
S20inetd
S20linuxlogo
S20logoutd
S20lprng
S89cron
S99xdm
Note que os arquivos que iniciam com o mesmo número (S20*) são executados
alfabeticamente. O nível de execução do sistema pode ser modificado usando-se o comando init
ou telinit. Os seguintes níveis de execução estão disponíveis no Debian:
15
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
- 0 - Interrompe a execução do sistema. Todos os programas e daemons2 finalizados. É
acionado pelo comando shutdown -h
- 1: Modo monousuário, útil para manutenção dos sistemas.
- 2: Modo multiusuário (padrão do Debian)
- 3: Modo multiusuário
- 4: Modo multiusuário
- 5: Modo multiusuário com login gráfico
- 6: Reinicialização do sistema. Todos os programas e daemons são encerrados e o sistema
é reiniciado. É acionado pelo comando shutdown -r e o pressionamento de CTRL+ALT+DEL.
Para listar o nível de execução atual do sistema digite:
$runlevel.
O runlevel deverá listar algo como:
N2
Agora para mudar para o nível de execução 1, digite:
$init 3
Agora confira a mudança digitando:
$runlevel
Você deverá ver este resultado:
23
Isto quer dizer que o nível de execução anterior era o 2 e o atual é o 3.
8. GERÊNCIA DE BOOT
Em informática, boot é o termo em inglês para o processo de iniciação do computador que
carrega o sistema operacional quando a máquina é ligada.
Muitos computadores podem executar apenas códigos existentes na memória de trabalho
(ROM ou RAM). Os sistemas operacionais modernos são normalmente armazenados em disco
rígido, CD-ROM ou outros dispositivos de armazenamento. Logo que o computador é ligado, ele
não tem um sistema operacional na memória. O hardware do computador não pode fazer as ações
do sistema operacional, como carregar um programa do disco. Assim, é criado um aparente
problema é criado para carregar o sistema operacional na memória.
2
Daemon – Acronimo para Disk And Execution MONitor é um programa de computador que roda em
background, ao invés de ser controlado diretamente por um usuário. Tipicamente, daemons têm nomes que
terminam com a letra "d"; por exemplo, syslogd é o daemon que gerencia o log do sistema. Muitas vezes,
um programa se torna um daemon através de um processo de fork seguido de o processo pai matar a si
mesmo, fazendo com que o init adote o processo criança. Essa prática é conhecida como "fork off and die".
Muitos sistemas iniciam daemons durante a inicialização do sistema. Os daemons muitas vezes têm o
propósito de responder a requisições de rede, atividades de hardware, ou outros programas. Daemons
também podem executar muitas outras tarefas, como executar tarefas em horários pré-determinados (como
o cron). Pode também ser definido como programa que fica rodando continuamente em uma máquina,
esperando uma requisição para executar alguma tarefa ou serviço.
16
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
A solução para o paradoxo está na utilização de um pequeno e especial programa,
chamado sistema de iniciação, boot loader ou bootstrap. Este programa não tem a completa
funcionalidade de um sistema operacional, mas é especialmente construído para que seja capaz de
carregar outro programa para permitir a iniciação do sistema operacional. Freqüentemente, boot
loaders de múltiplos estágios são usados. Neste caso, vários pequenos programas se
complementam em seqüência até que o último deles carregue o sistema operacional.
Esse processo é o primeiro a ser executado quando o computador é ligado, sendo o boot
responsável pela carga do sistema operacional na memória principal (RAM).
Nos computadores modernos o processo de iniciação começa com a execução pela CPU de
um programa contido na memória ROM (o BIOS - Basic Input/Output System do IBM PC) em um
endereço predefinido (a CPU é programada para executar este programa depois de um reset
automaticamente). Este programa contém funcionalidades rudimentares para procurar por
dispositivos que podem conter um sistema operacional e que são, portanto, passíveis de participar
de um boot. Definido o dispositivo é carregado um pequeno programa de uma seção especial
deste.
No segundo estágio da inicialização um pequeno programa que normalmente não é o
sistema operacional, será o responsável por carregar o sistema operacional apropriado, e
finalmente transferir a execução para ele. O sistema, então, irá inicializar, carregar drivers de
dispositivos (device drivers) e outros programas que são necessários para a operação normal de
um sistema operacional. Exemplos de programas responsáveis por estas tarefas no GNU/Linux são
o GRUB e LILO.
O processo de inicialização é considerado completo quando o computador está pronto para
ser operado pelo usuário.
8.1. Gerenciadores de Boot
O Linux, assim como todo Sistema Operacional, precisa de um bootloader para ser
carregado em memória e entrar em operação.
8.1.1. LILO
O LILO é um acrônimo para a expressão inglesa LInux LOader que, em português, significa
carregador de Linux. É um bootloader, gestor de arranque ou gerenciador de Sistemas
Operacionais. Permite configurar o arranque (Boot) de múltiplos sistemas operativos na mesma
máquina (não simultaneamente).
Para isso, instala-se nos primeiros 512 bytes de qualquer dispositivo de armazenamento
(MBR - Master Boot Record), imediatamente antes da tabela de partições. Como tal, é
independente do(s) sistema(s) operacional(ais) instalado(s) e seus sistemas de arquivos, mas é,
obrigatoriamente, escrito em código-máquina e fortemente dependente da plataforma.
O LILO permite escolher um de dezesseis kernels possíveis, cada um contendo opções
específicas.
8.1.2. GRUB
17
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
Em computação, GNU GRUB (ou apenas GRUB) é um multi-carregador de um sistema
operacional criado pelo projeto GNU. É utilizado, normalmente, quando se deseja que um
computador tenha dual booting, ou seja, que o usuário possa escolher ao iniciar a máquina, um
sistema operacional dentre dois ou mais sistemas instalados. Ele é um programa que pode
carregar qualquer arquivo executável com um cabeçalho multi boot nos seus primeiros 8 kB.
O GNU GRUB foi desenvolvido a partir de um pacote chamado GRand Unified Bootloader,
de onde deriva o acrônimo GRUB.
Atualmente em desenvolvimento, o GRUB 2 substituiu o GRUB que passou a chamar-se
GRUB Legacy (ou, em português, GRUB legado).
O processo de carregamento do sistema operacional usando o GRUB segue os seguintes
passos:
1. O BIOS busca um dispositivo que faça o carregamento do Sistema Operacional
(normalmente um disco rígido) e move o controle para o MBR. O MBR é situado nos 512 primeiros
bytes do disco;
2. O MBR contém o estágio 1 do GRUB. Dado o pequeno tamanho deste estágio, ele
apenas carrega o próximo estágio do GRUB (que pode residir em qualquer lugar no disco). O
estágio 1 pode carregar o estágio 1.5 ou o estágio 2 diretamente;
3. O estágio 1.5 é localizado nos 30 primeiros Kb do disco imediatamente após o MBR. O
estágio 1.5 carrega o estágio 2;
4. O estágio 2 recebe o controle, e mostra ao usuário o menu com as opções de sistemas
operacionais instalados no sistema;
5. O GRUB carrega na memória o kernel do Sistema Operacional escolhido e passa o
controle ao kernel.
Para sistemas operacionais que o GRUB não suporta totalmente, o controle é passado para
outro carregador que continua o processo até carregar o kernel em memória como é o caso do
Windows em suas diversas versões.
Figura 16 - Lilo
8.1.3. CONFIGURAÇÃO DO GRUB
18
SISTEMAS OPERACIONAIS ABERTOS
Prof. Ricardo Rodrigues Barcelar
http://www.ricardobarcelar.com.br
Em geral, o bootloader está localizado na partição ou diretório /boot do sistema
Operacional GNU/Linux. Nas versões mais antigas do GRUB (GRUB Legacy) o arquivo que permite
a seleção do Sistema Operacional é o /boot/grub/menu.lst.
O /boot/grub/menu.lst do GRUB legacy foi substituído por /boot/grub/grub.cfg no GRUB .
O arquivo grub.cfg é atualizado automaticamente sempre que for incluída ou retirada uma versão
do kernel.
As configurações do menu principal residem no arquivo /etc/default/grub. Para
acrescentar entradas adicionais ao menu utilize o arquivo etc/grub.d/40_custom.
Para que as atualizações sejam efetivadas é necessário executar o update-grub.
As versões mais atuais do Ubuntu utilizam o GRUB2. Informações pormenorizadas sobre a
configuração deste bootloader pode ser encontrada em
https://help.ubuntu.com/community/Grub2
Figura 17 – GRUB
Outras informações técnicas acerca de gerenciadores de boot podem ser encontradas em
http://www.ibm.com/developerworks/br/library/l-lpic1-v3-102-2/#3-lilo
19

Documentos relacionados