Quais são as diferenças entre memória virtual e memória física?

102

Muitas vezes me confundo com o conceito de virtualização em sistemas operacionais. Considerando a RAM como a memória física, por que precisamos da memória virtual para executar um processo?

Onde fica essa memória virtual quando o processo (programa) do disco rígido externo é trazido para a memória principal (memória física) para a execução.

Quem cuida da memória virtual e qual é o tamanho da memória virtual?

Suponha que se o tamanho da RAM for 4 GB (ou seja, 2 ^ 32-1 espaços de endereço), qual é o tamanho da memória virtual?

starkk92
fonte
2
E se você tiver 512 MB e precisar endereçar 4 GB?
Oded de
apenas a parte necessária do programa é trazida para a memória principal. Por favor, corrija-me se eu estiver errado. Obrigado ..
starkk92
3
A "memória virtual" é como os cegos inspecionando o elefante. Cada um terá uma impressão diferente.
Hot Licks de
2
Para aqueles de vocês que desejam uma resposta detalhada, certifique-se de verificar esta resposta.
RickyA
Programas TSR em dos relacionados: en.m.wikipedia.org/wiki/Terminate_and_stay_resident_program
EsmaeelE

Respostas:

85

A memória virtual é, entre outras coisas, uma abstração para dar ao programador a ilusão de ter memória infinita disponível em seu sistema.

Os mapeamentos de memória virtual são feitos para corresponder aos endereços físicos reais. O sistema operacional cria e lida com esses mapeamentos - utilizando a tabela de páginas, entre outras estruturas de dados para manter os mapeamentos. Os mapeamentos de memória virtual são sempre encontrados na tabela de páginas ou em alguma estrutura de dados semelhante (no caso de outras implementações de memória virtual, talvez não devêssemos chamá-la de "tabela de páginas"). A tabela de páginas também está na memória física - geralmente em espaços reservados pelo kernel que os programas do usuário não podem substituir.

A memória virtual é normalmente maior do que a memória física - não haveria muitos motivos para mapeamentos de memória virtual se a memória virtual e a memória física fossem do mesmo tamanho.

Apenas a parte necessária de um programa reside na memória, normalmente - este é um tópico chamado "paginação". A memória virtual e a paginação estão intimamente relacionadas, mas não são o mesmo tópico. Existem outras implementações de memória virtual, como segmentação.

Eu posso estar supondo que estou errado aqui, mas aposto que as coisas que você está achando difícil entender têm a ver com implementações específicas de memória virtual, provavelmente paginação. Não há uma maneira de fazer paginação - há muitas implementações e aquela que seu livro descreve provavelmente não é a mesma que aparece em sistemas operacionais reais como Linux / Windows - provavelmente há diferenças sutis.

Eu poderia tagarelar milhares de parágrafos sobre paginação ... mas acho que é melhor deixar para uma pergunta diferente direcionada especificamente a esse tópico.

PinkElephantsOnParade
fonte
4
Existem razões para ter a memória virtual e a memória física do mesmo tamanho. A VM permite que diferentes processos tenham seus próprios espaços de endereço. Isso protege os dados de um processo de serem sobrescritos por outro processo. Ele também permite que você conceda diferentes permissões a diferentes espaços de endereçamento, de forma que alguns usuários do sistema possam ter privilégios de leitura / gravação maiores do que outros. Ter a mesma quantidade de memória virtual e memória física elimina os benefícios de armazenamento da VM, no entanto.
almel
1
Para adicionar ao comentário de almel: Mesmo quando há uma memória virtual menor ou do mesmo tamanho do que a memória física: além dos benefícios de segurança e estabilidade, vários programas de 32 bits podem ser executados na memória que de outra forma não seriam capazes (por exemplo, em um Sistema de 64 bits), a memória física pode ser gerenciada melhor para evitar alguns problemas com fragmentação, técnicas de memória de cópia na gravação transparente exigem VM, etc ...
Kaganar
2
Observe bem que a memória virtual não é de forma alguma "infinita", nem tal projeto pretende inspirar tais ilusões. A arquitetura AMD64 atualmente permite o endereçamento de 48 bits de memória virtual ( AMD APM Vol 2. pág. 120 ) Embora os casos de uso variem, pode-se argumentar que uma grande vantagem é a capacidade de reservar corridas contíguas substancialmente maiores do espaço de endereço do que seria comumente possível no espaço físico. Esse intervalo reservado é então comprometido sob demanda, o que pode eliminar a necessidade de estruturas vinculadas, bem como de realocação.
awdz9nld
Há algum livro que eu possa ler sobre esse tipo de coisa, ou seja, sobre memória virtual, seu layout, a técnica de paginação em detalhes elaborados? Onde posso aprender o básico de tudo isso?
Water Cooler v2
@ WaterCoolerv2 Eu gosto de "Sistemas de Computador: Uma Abordagem Integrada para Arquitetura e Sistemas Operacionais" de Umakishore Ramachandran. É um livro didático, mas acho que é bastante completo e explica as coisas bem em comparação com outros livros sobre sistemas operacionais. Mas, na verdade, quase todos os livros sobre o tópico de sistemas operacionais irão provavelmente passar por paginação, memória virtual, etc.
PinkElephantsOnParade
85

Os softwares são executados no sistema operacional em uma premissa muito simples - eles requerem memória. O sistema operacional do dispositivo fornece isso na forma de RAM. A quantidade de memória necessária pode variar - alguns softwares precisam de muita memória, outros requerem memória insignificante. A maioria (senão todos) dos usuários executa vários aplicativos no sistema operacional simultaneamente e, como a memória é cara (e o tamanho do dispositivo é finito), a quantidade de memória disponível é sempre limitada. Assim, dado que todos os softwares requerem uma certa quantidade de RAM, e todos podem ser executados ao mesmo tempo, o sistema operacional tem que cuidar de duas coisas:

  1. Que o software sempre seja executado até que o usuário o aborte, ou seja, ele não deve abortar automaticamente porque o sistema operacional ficou sem memória.
  2. A atividade acima, mantendo um desempenho respeitável para os softwares em execução.

Agora a questão principal se resume a como a memória está sendo gerenciada. O que exatamente governa onde os dados pertencentes a um determinado software residirão na memória?

Solução possível 1 : permitir que softwares individuais especifiquem explicitamente o endereço de memória que usarão no dispositivo. Suponha que o Photoshop declare que sempre usará endereços de memória variando de 0a 1023(imagine a memória como um array linear de bytes, então o primeiro byte está no local 0, o 1024byte está no local 1023) - isto é, ocupando 1 GBmemória. Da mesma forma, o VLC declara que ocupará intervalo de memória 1244para 1876, etc.

Vantagens:

  1. Cada aplicativo é pré-atribuído a um slot de memória, então quando é instalado e executado, ele apenas armazena seus dados naquela área de memória e tudo funciona bem.

Desvantagens:

  1. Isso não escala. Teoricamente, um aplicativo pode exigir uma grande quantidade de memória quando está fazendo algo realmente pesado. Portanto, para garantir que nunca fique sem memória, a área de memória alocada a ele deve ser sempre maior ou igual a essa quantidade de memória. E se um software, cujo uso máximo teórico de memória é 2 GB(portanto, exigindo 2 GBalocação de memória da RAM), for instalado em uma máquina com apenas 1 GBmemória? O software deve simplesmente abortar na inicialização, informando que a RAM disponível é menor que 2 GB? Ou deve continuar e, no momento em que a memória necessária ultrapassar 2 GB, apenas abortar e sair com a mensagem de que não há memória suficiente disponível?

  2. Não é possível evitar a mutilação da memória. Existem milhões de softwares por aí, mesmo que cada um deles tivesse apenas 1 kBmemória, o total de memória necessária seria excedido 16 GB, o que é mais do que a maioria dos dispositivos oferece. Como podem, então, diferentes softwares receber slots de memória que não invadam as áreas uns dos outros? Em primeiro lugar, não existe um mercado centralizado de software que possa regular que quando um novo software está sendo lançado, ele deve atribuir a si mesmo essa quantidade de memória desta área ainda não ocupadae, em segundo lugar, mesmo que houvesse, não é possível porque o não. de softwares é praticamente infinito (exigindo memória infinita para acomodar todos eles), e a RAM total disponível em qualquer dispositivo não é suficiente para acomodar nem mesmo uma fração do que é necessário, tornando inevitável a invasão dos limites de memória de um software sobre o de outro. Então, o que acontece quando Photoshop é atribuído posições de memória 1para 1023e VLC é atribuído 1000a 1676? E se o Photoshop armazenar alguns dados no local 1008, o VLC sobrescrever isso com seus próprios dados e, posteriormente, o Photoshopacessa pensando que são os mesmos dados que estavam armazenados lá anteriormente? Como você pode imaginar, coisas ruins acontecerão.

Então, claramente, como você pode ver, essa ideia é um tanto ingênua.

Possível solução 2 : vamos tentar outro esquema - onde o SO fará a maior parte do gerenciamento de memória. Os softwares, sempre que necessitarem de alguma memória, apenas solicitarão o SO, e o SO se acomodará de acordo. Say OS garante que sempre que um novo processo está solicitando memória, ele alocará a memória do endereço de byte mais baixo possível (como disse anteriormente, a RAM pode ser imaginada como uma matriz linear de bytes, portanto, para uma 4 GBRAM, o intervalo de endereços para um byte de 0para2^32-1) se o processo estiver iniciando, caso contrário, se for um processo em execução solicitando a memória, ele alocará a partir do último local de memória onde esse processo ainda reside. Uma vez que os softwares estarão emitindo endereços sem considerar qual será o endereço real da memória onde os dados são armazenados, o sistema operacional terá que manter um mapeamento, por software, do endereço emitido pelo software para o endereço físico real (Nota: essa é uma das duas razões pelas quais chamamos esse conceito Virtual Memory. Os softwares não se importam com o endereço de memória real onde seus dados estão sendo armazenados, eles apenas cuspem os endereços na hora, e o sistema operacional encontra o lugar certo para encaixá-los e encontrá-los mais tarde, se necessário).

Digamos que o dispositivo acabou de ser ligado, o sistema operacional acabou de iniciar, no momento não há nenhum outro processo em execução (ignorando o sistema operacional, que também é um processo!) E você decide iniciar o VLC . Portanto, o VLC recebe uma parte da RAM dos endereços de byte mais baixo. Boa. Agora, enquanto o vídeo está sendo executado, você precisa iniciar seu navegador para visualizar alguma página da web. Em seguida, você precisa iniciar o Bloco de notas para rabiscar algum texto. E então Eclipse para fazer alguma codificação .. Logo sua memória 4 GBé toda usada, e a RAM fica assim:

                                   insira a descrição da imagem aqui

Problema 1: Agora você não pode iniciar nenhum outro processo, pois toda a RAM está esgotada. Assim, os programas devem ser escritos tendo em mente o máximo de memória disponível (praticamente ainda menos estará disponível, já que outros softwares também estarão rodando paralelamente!). Em outras palavras, você não pode executar um aplicativo que consome muita memória em seu 1 GBPC decrépito .

Ok, agora que você decidiu que não precisa mais manter o Eclipse e o Chrome abertos, feche-os para liberar memória. O espaço ocupado na RAM por esses processos é recuperado pelo SO e se parece com isto agora:

                                    insira a descrição da imagem aqui

Suponha que fechar esses dois libera 700 MBespaço - ( 400+ 300) MB. Agora você precisa iniciar o Opera , que ocupará 450 MBespaço. Bem, você tem mais do que 450 MBespaço disponível no total, mas ... não é contíguo, é dividido em pedaços individuais, nenhum dos quais é grande o suficiente para caber 450 MB. Então você teve uma ideia brilhante, vamos mover todos os processos abaixo para o mais alto possível, o que deixará o 700 MBespaço vazio em um pedaço na parte inferior. Isso é chamadocompaction. Ótimo, exceto que ... todos os processos que existem estão em execução. Movê-los significará mover o endereço de todo o seu conteúdo (lembre-se, o SO mantém um mapeamento da memória cuspida pelo software para o endereço de memória real. Imagine que o software cuspiu um endereço de 45com dados 123e o SO o armazenou no local 2012e criou uma entrada no mapa, mapeando 45para 2012. Se o software agora for movido na memória, o que costumava estar no local 2012não estará mais 2012, mas em um novo local, e o sistema operacional precisa atualizar o mapa de acordo para mapear 45para o novo endereço, para que o software possa obter os dados esperados ( 123) ao consultar a localização da memória 45. No que diz respeito ao software, tudo o que ele conhece é esse endereço45contém os dados 123!)! Imagine um processo que faz referência a uma variável local i. No momento em que for acessado novamente, seu endereço mudou e ele não poderá mais encontrá-lo. O mesmo vale para todas as funções, objetos, variáveis, basicamente tudo tem um endereço, e mover um processo significará mudar o endereço de todos eles. O que nos leva a:

Problema 2: Você não pode mover um processo. Os valores de todas as variáveis, funções e objetos dentro desse processo têm valores codificados como cuspidos pelo compilador durante a compilação, o processo depende deles estarem no mesmo local durante seu tempo de vida e alterá-los é caro. Como resultado, os processos deixam um grande " holes" para trás quando são encerrados. Isso é chamado External Fragmentation.

Bem. Suponha que de alguma forma, de alguma maneira milagrosa, você consiga mover os processos para cima. Agora há 700 MBespaço livre na parte inferior:

                        insira a descrição da imagem aqui

O Opera se encaixa perfeitamente na parte inferior. Agora sua RAM se parece com isto:

                                    insira a descrição da imagem aqui

Boa. Tudo parece bem. No entanto, não há muito espaço disponível e agora você precisa iniciar o Chrome novamente, um conhecido devorador de memória! Ele precisa de muita memória para iniciar e você quase não tem memória sobrando ... Exceto ... você agora percebe que alguns dos processos, que inicialmente ocupavam um grande espaço, agora não estão precisando de muito espaço. Pode ser que você tenha interrompido seu vídeo no VLC , portanto, ele ainda está ocupando algum espaço, mas não tanto quanto o necessário durante a execução de um vídeo de alta resolução. Da mesma forma para o bloco de notas e fotos . Sua RAM agora se parece com isto:

                                        insira a descrição da imagem aqui

Holes, de novo! De volta à estaca zero! Exceto, anteriormente, os buracos ocorriam devido ao encerramento de processos, agora são devido a processos que exigiam menos espaço do que antes! E você novamente tem o mesmo problema, os holescombinados rendem mais espaço do que o necessário, mas eles estão espalhados, não muito úteis isoladamente. Portanto, você precisa mover esses processos novamente, uma operação cara e muito frequente, já que os processos freqüentemente reduzem de tamanho ao longo de sua vida útil.

Problema 3: Os processos, ao longo de sua vida útil, podem reduzir de tamanho, deixando para trás espaço não utilizado, que, se necessário, exigirá a operação cara de mover muitos processos. Isso é chamado Internal Fragmentation.

Tudo bem, então agora seu sistema operacional faz o necessário, move os processos e inicia o Chrome e, depois de algum tempo, sua RAM fica assim:

insira a descrição da imagem aqui

Legal. Agora, suponha que você volte a assistir Avatar no VLC . Sua necessidade de memória vai disparar! Mas ... não há espaço para crescer, pois o bloco de notas está aninhado em sua parte inferior. Portanto, novamente, todos os processos devem ser movidos para baixo até que o VLC encontre espaço suficiente!

Problema 4: Se os processos precisarem crescer, será uma operação muito cara

Bem. Agora, suponha que o Fotos esteja sendo usado para carregar algumas fotos de um disco rígido externo. Acessar o disco rígido leva você do reino dos caches e RAM para o do disco, que é mais lento por ordens de grandeza. Dolorosamente, irrevogavelmente, transcendentalmente mais lento. É uma operação de E / S, o que significa que não está vinculada à CPU (é exatamente o oposto), o que significa que não precisa ocupar RAM agora. No entanto, ele ainda ocupa a RAM teimosamente. Se você quiser iniciar o Firefox nesse ínterim, não pode, porque não há muita memória disponível, ao passo que se o Fotos fosse tirado da memória durante sua atividade de I / O, ele teria liberado muita memória, seguido pela compactação (cara), seguida pelo encaixe do Firefox .

Problema 5: os trabalhos vinculados a E / S continuam ocupando RAM, levando à subutilização de RAM, que poderia ter sido usada por trabalhos vinculados à CPU nesse ínterim.

Então, como podemos ver, temos tantos problemas até com a abordagem da memória virtual.


Existem duas abordagens para lidar com esses problemas - paginge segmentation. Deixe-nos discutir paging. Nessa abordagem, o espaço de endereço virtual de um processo é mapeado para a memória física em blocos - chamados pages. Um pagetamanho típico é 4 kB. O mapeamento é mantido por algo chamado de page table, dado um endereço virtual, tudo o que agora temos que fazer é descobrir a que pageo endereço pertence, em seguida page table, encontrar o local correspondente para aquele pagena memória física real (conhecido como frame), e dado se o deslocamento do endereço virtual dentro do pageé o mesmo para o pagee também para o frame, descubra o endereço real adicionando esse deslocamento ao endereço retornado pelo page table. Por exemplo:

insira a descrição da imagem aqui

À esquerda está o espaço de endereço virtual de um processo. Digamos que o espaço de endereço virtual requer 40 unidades de memória. Se o espaço de endereço físico (à direita) também tivesse 40 unidades de memória, seria possível mapear todas as localizações da esquerda para uma localização à direita, e teríamos ficado muito felizes. Mas, por azar, não apenas a memória física tem menos (24 aqui) unidades de memória disponíveis, ela também deve ser compartilhada entre vários processos! Tudo bem, vamos ver como faremos com isso.

Quando o processo começa, digamos que uma solicitação de acesso à memória para localização 35seja feita. Aqui, o tamanho da página é 8(cada um pagecontém 8locais, todo o espaço de endereço virtual dos 40locais, portanto, contém 5páginas). Portanto, este local pertence à página no. 4( 35/8). Dentro disso page, este local tem um deslocamento de 3( 35%8). Portanto, este local pode ser especificado pela tupla (pageIndex, offset)= (4,3). Este é apenas o começo, então nenhuma parte do processo é armazenada na memória física real ainda. Assim page table, o , que mantém um mapeamento das páginas à esquerda para as páginas reais à direita (onde são chamadasframes) está vazio no momento. Assim, o sistema operacional abre mão da CPU, permite que um driver de dispositivo acesse o disco e busque a página nº. 4para este processo (basicamente um pedaço de memória do programa no disco, cujos endereços variam de 32a 39). Quando chega, o sistema operacional aloca a página em algum lugar da RAM, digamos o próprio primeiro quadro, e o page tablepara este processo toma nota de que a página 4mapeia para o quadro 0na RAM. Agora, os dados estão finalmente na memória física. O SO consulta novamente a tabela de páginas para a tupla (4,3)e, desta vez, a tabela de páginas diz que a página 4já está mapeada para o quadro 0na RAM. Assim, o sistema operacional simplesmente vai para o 0º quadro na RAM, acessa os dados no deslocamento 3desse quadro (reserve um momento para entender isso.page, que foi obtido do disco, é movido para frame. Portanto, seja qual for o deslocamento de um local de memória individual em uma página, ele será o mesmo no quadro também, já que dentro de page/ frame, a unidade de memória ainda reside no mesmo lugar relativamente!) E retorna os dados! Como os dados não foram encontrados na memória na primeira consulta em si, mas tiveram que ser buscados do disco para serem carregados na memória, isso constitui um erro .

Bem. Agora suponha que 28seja feito um acesso à memória para localização . Tudo se resume a (3,4). Page tableagora tem apenas uma entrada, mapeamento de página 4para quadro 0. Portanto, isso é novamente uma falha , o processo cede a CPU, o driver do dispositivo busca a página do disco, o processo recupera o controle da CPU novamente e ele page tableé atualizado. Digamos que agora a página 3esteja mapeada para quadro 1na RAM. Assim, (3,4)torna-se (1,4), e os dados nesse local na RAM é retornado. Boa. Dessa forma, suponha que o próximo acesso à memória seja por localização 8, que se traduz em (1,0). A página 1ainda não está na memória, o mesmo procedimento é repetido e o pageestá alocado no quadro2na RAM. Agora, o mapeamento do processo de RAM se parece com a imagem acima. Neste momento, a RAM, que tinha apenas 24 unidades de memória disponível, está cheia. Suponha que a próxima solicitação de acesso à memória para este processo seja do endereço 30. Ele mapeia para (3,6)e page tablediz que a página 3está na RAM e mapeia para o quadro 1. Yay! Portanto, os dados são buscados no local da RAM (1,6)e retornados. Isso constitui um sucesso , pois os dados necessários podem ser obtidos diretamente da RAM, sendo, portanto, muito rápidos. Da mesma forma, as próximas solicitações de acesso, digamos, por locais 11, 32, 26, 27todos são acertos , ou seja, dados solicitados pelo processo encontra-se diretamente na RAM sem a necessidade de procurar em outro lugar.

Agora, suponha que uma solicitação de acesso à memória para localização 3venha. Isso se traduz em (0,3), e page tablepara este processo, que atualmente tem 3 entradas, para páginas 1, 3e 4diz que esta página não está na memória. Como nos casos anteriores, ele é obtido do disco; no entanto, ao contrário dos casos anteriores, a RAM está cheia! Então o que fazer agora? Aqui está a beleza da memória virtual, um quadro da RAM é despejado! (Vários fatores determinam qual quadro deve ser removido. Pode ser LRUbaseado, onde o quadro que foi acessado menos recentemente para um processo deve ser removido. Pode ser a first-come-first-evictedbase, onde o quadro que alocou há mais tempo, é removido, etc. .) Portanto, algum quadro é despejado. Diga o quadro 1 (apenas escolhendo aleatoriamente). No entanto, isso frameé mapeado para algunspage! (Atualmente, ele é mapeado pela tabela de página para página 3de nosso único processo). Portanto, esse processo tem que ser informado desta notícia trágica, aquele frame, que infelizmente pertence a você, é ser despejado da RAM para dar lugar a outro pages. O processo deve garantir que ele se atualize page tablecom essas informações, ou seja, removendo a entrada para aquela dupla de page-frame, para que na próxima vez que for feito um pedido para isso page, ele diga corretamente ao processo que isso pagenão está mais na memória , e deve ser obtido do disco. Boa. Assim, o quadro 1é removido, a página 0é trazida e colocada lá na RAM e a entrada da página 3é removida e substituída pelo 0mapeamento de página para o mesmo quadro1. Portanto, agora nosso mapeamento se parece com isto (observe a mudança de cor no segundo framedo lado direito):

insira a descrição da imagem aqui

Viu o que aconteceu? O processo precisava crescer, precisava de mais espaço do que a RAM disponível, mas, ao contrário de nosso cenário anterior, onde todos os processos na RAM precisavam ser movidos para acomodar um processo crescente, aqui aconteceu com apenas uma pagesubstituição! Isso foi possível pelo fato de que a memória de um processo não precisa mais ser contígua, pode residir em diferentes locais em blocos, o SO mantém as informações de onde eles estão e, quando necessário, são devidamente consultados. Observação: você pode estar pensando, hein, e se na maioria das vezes for um misse os dados precisarem ser carregados constantemente do disco para a memória? Sim, teoricamente, é possível, mas a maioria dos compiladores são projetados da maneira que seguelocality of reference, ou seja, se forem usados ​​dados de algum local da memória, os próximos dados necessários estarão localizados em algum lugar muito próximo, talvez do mesmo page, pageque acabou de ser carregado na memória. Como resultado, a próxima falha ocorrerá depois de algum tempo, a maioria dos requisitos de memória futuros serão atendidos pela página que acabou de ser trazida ou pelas páginas já na memória que foram usadas recentemente. Exatamente o mesmo princípio nos permite expulsar também o menos usado recentemente page, com a lógica de que o que não foi usado por um tempo, provavelmente não será usado por um tempo também. Porém, nem sempre é assim e, em casos excepcionais, sim, o desempenho pode ser prejudicado. Mais sobre isso mais tarde.

Solução para o problema 4: Os processos agora podem crescer facilmente; se houver problema de espaço, tudo o que é necessário é fazer uma pagesubstituição simples , sem mover nenhum outro processo.


Solução para o problema 1: um processo pode acessar memória ilimitada. Quando é necessária mais memória do que a disponível, o disco é usado como backup, os novos dados necessários são carregados na memória a partir do disco e os dados menos usados ​​recentemente frame(ou page) são movidos para o disco. Isso pode continuar infinitamente e, como o espaço em disco é barato e virtualmente ilimitado, dá uma ilusão de memória ilimitada. Outra razão para o nome Virtual Memory, dá a ilusão de memória que não está realmente disponível!

Legal. Anteriormente, estávamos enfrentando um problema em que, embora um processo seja reduzido em tamanho, o espaço vazio é difícil de ser recuperado por outros processos (porque isso exigiria uma compactação cara). Agora é fácil, quando um processo se torna menor em tamanho, muitos dos seus pagesnão são mais usados, então quando outros processos precisam de mais memória, um LRUdespejo baseado em simples despeja automaticamente aqueles menos usados pagesda RAM e os substitui pelas novas páginas de os outros processos (e claro atualizar o page tablesde todos esses processos, bem como o processo original que agora requer menos espaço), todos esses sem nenhuma operação de compactação cara!

Solução para o problema 3: sempre que os processos diminuem de tamanho, sua framesmemória RAM será menos usada, portanto, um LRUdespejo de base simples pode remover essas páginas e substituí-las pelas pagesexigidas por novos processos, evitando assim Internal Fragmentationsem necessidade compaction.

Quanto ao problema 2, pare um momento para entender isso, o cenário em si foi completamente removido! Não há necessidade de mover um processo para acomodar um novo processo, porque agora o processo inteiro nunca precisa caber de uma vez, apenas algumas páginas dele precisam caber ad hoc, o que acontece com o despejo framesda RAM. Tudo acontece em unidades de pages, portanto, não há conceito de holeagora e, portanto, nenhuma questão de movimento! Dez de maio pagestiveram que ser movidos devido a esse novo requisito, milhares dos pagesquais foram deixados intactos. Considerando que, anteriormente, todos os processos (cada pedaço deles) tinham que ser movidos!

Solução para o problema 2: para acomodar um novo processo, os dados apenas de partes menos usadas de outros processos devem ser removidos conforme necessário, e isso acontece em unidades de tamanho fixo chamadas pages. Portanto, não há possibilidade de holeou External Fragmentationcom este sistema.

Agora, quando o processo precisa fazer alguma operação de E / S, ele pode abandonar a CPU facilmente! O sistema operacional simplesmente remove todos os seus pagesda RAM (talvez armazene-os em algum cache) enquanto novos processos ocupam a RAM nesse meio tempo. Quando a operação de I / O é feita, o SO simplesmente os restaura pagespara a RAM (claro, substituindo o pagesde alguns outros processos, podem ser daqueles que substituíram o processo original, ou podem ser de alguns que precisam fazer I / Oh, agora, e, portanto, pode renunciar à memória!)

Solução para o problema 5: quando um processo está executando operações de E / S, ele pode facilmente desistir do uso de RAM, que pode ser utilizado por outros processos. Isso leva à utilização adequada da RAM.

E, claro, agora nenhum processo está acessando a RAM diretamente. Cada processo está acessando um local de memória virtual, que é mapeado para um endereço de RAM físico e mantido pelo page-tabledesse processo. O mapeamento é apoiado pelo sistema operacional, o sistema operacional permite que o processo saiba qual quadro está vazio para que uma nova página para um processo possa ser ajustada lá. Uma vez que esta alocação de memória é supervisionada pelo próprio sistema operacional, pode facilmente garantir que nenhum processo invada o conteúdo de outro processo, alocando apenas quadros vazios da RAM, ou ao invadir o conteúdo de outro processo na RAM, comunique-se com o processo para atualizá-lo page-table.

Solução para o problema original: não há possibilidade de um processo acessar o conteúdo de outro processo, uma vez que toda a alocação é gerenciada pelo próprio SO e cada processo é executado em seu próprio espaço de endereço virtual em sandbox.

Então paging(entre outras técnicas), em conjunto com a memória virtual, é o que alimenta os softwares de hoje rodando em sistemas operacionais! Isso libera o desenvolvedor de software de se preocupar com quanta memória está disponível no dispositivo do usuário, onde armazenar os dados, como evitar que outros processos corrompam os dados de seu software, etc. No entanto, é claro, não é totalmente à prova. Existem falhas:

  1. Pagingé, em última análise, dar ao usuário a ilusão de memória infinita usando o disco como backup secundário. Recuperar dados do armazenamento secundário para caber na memória (chamado page swap, e o caso de não encontrar a página desejada na RAM é chamado page fault) é caro, pois é uma operação de E / S. Isso retarda o processo. Várias dessas trocas de página acontecem em sucessão, e o processo se torna dolorosamente lento. Você já viu seu software rodando bem e de repente ele se torna tão lento que quase trava, ou deixa você sem opção de reiniciá-lo? Possivelmente, muitas trocas de página estavam acontecendo, tornando-o lento (chamado thrashing).

Então, voltando ao OP,

Por que precisamos da memória virtual para executar um processo? - Como a resposta explica longamente, dar aos softwares a ilusão de que o dispositivo / SO tem memória infinita, de forma que qualquer software, grande ou pequeno, possa ser executado, sem se preocupar com a alocação de memória, ou outros processos que corrompam seus dados, mesmo quando correndo em paralelo. É um conceito, implementado na prática por meio de várias técnicas, uma das quais, conforme descrito aqui, é o Paging . Também pode ser segmentação .

Onde fica essa memória virtual quando o processo (programa) do disco rígido externo é trazido para a memória principal (memória física) para a execução? - A memória virtual não está em lugar nenhum por si, é uma abstração, sempre presente, quando o software / processo / programa é inicializado, uma nova tabela de páginas é criada para ele, e contém o mapeamento dos endereços cuspidos por aquele processo para o endereço físico real na RAM. Uma vez que os endereços cuspidos pelo processo não são endereços reais, em certo sentido, eles são, na verdade, o que você pode dizer the virtual memory,.

Quem cuida da memória virtual e qual é o tamanho da memória virtual? - É cuidado, em conjunto, o SO e o software. Imagine uma função em seu código (que eventualmente foi compilada e transformada no executável que gerou o processo) que contém uma variável local - um int i. Quando o código é executado, iobtém um endereço de memória na pilha da função. Essa função é armazenada como um objeto em outro lugar. Esses endereços são gerados pelo compilador (o compilador que compilou seu código no executável) - endereços virtuais. Quando executado, ideve residir em algum lugar no endereço físico real para a duração dessa função, pelo menos (a menos que seja uma variável estática!), Então o sistema operacional mapeia o endereço virtual gerado pelo compiladoriem um endereço físico real, de modo que sempre que, dentro dessa função, algum código exigir o valor de i, esse processo pode consultar o sistema operacional para esse endereço virtual e o sistema operacional por sua vez pode consultar o endereço físico para o valor armazenado e retorná-lo.

Suponha que se o tamanho da RAM for 4 GB (ou seja, 2 ^ 32-1 espaços de endereço), qual é o tamanho da memória virtual? - O tamanho da RAM não está relacionado ao tamanho da memória virtual, depende do sistema operacional. Por exemplo, no Windows de 32 bits, sim 16 TB, no Windows de 64 bits, sim 256 TB. Obviamente, também é limitado pelo tamanho do disco, já que é nele que é feito o backup da memória.

SexyBeast
fonte
2
Esta é uma excelente descrição detalhada de VM / paginação (deve ser uma postagem de blog em algum lugar). A única parte do mapeamento / paginação da VM que me confunde é que ainda requer (aparentemente) muitos acessos ao disco para cada falha de página ou troca. Cada troca de página (da VM para o disco e vice-versa) chama uma leitura / gravação para o disco? Isso parece ser uma grande sobrecarga para mim.
Aroic de
@TMartin sim, a página é gravada em pagefile.sys e acredito que haja 2 gravações, uma para a página e outra para o PFN que fica armazenado em uma matriz dentro do arquivo de paginação. O algoritmo LRU garante que principalmente a página do PTE menos acessado de cada conjunto de trabalho de processo (idade mais velha) será enviada para a lista de espera e, eventualmente, paginada, portanto, é provável que a página tenha sido gravada em disco há muito tempo antes dela é acessado novamente, então isso acontecerá em segundo plano. Também é um evento relativamente incomum no grande esquema das coisas; a maioria das falhas de página serão suaves.
Lewis Kelsey
A lista de espera também tem um sistema de prioridade própria e quando a lista zero e livre estiver vazia, ela começará a paginar as páginas de espera com a prioridade mais baixa. Não tenho certeza em que a prioridade se baseia, mas pode corresponder a uma era LRU anterior
Lewis Kelsey
16

Estou copiando descaradamente os trechos da página de manual do topo

VIRT - Imagem Virtual (kb) A quantidade total de memória virtual usada pela tarefa. Inclui todos os códigos, dados e bibliotecas compartilhadas, além de páginas que foram trocadas e páginas que foram mapeadas, mas não usadas.

SWAP - Memória de tamanho trocada (kb) que não é residente, mas está presente em uma tarefa. Esta é a memória que foi trocada, mas pode incluir memória não residente adicional. Esta coluna é calculada subtraindo a memória física da memória virtual

Cleonjoys
fonte
5

Veja aqui: Memória Física Vs Memória Virtual

A memória virtual é armazenada no disco rígido e é usada quando a RAM está cheia. A memória física é limitada ao tamanho dos chips de RAM instalados no computador. A memória virtual é limitada pelo tamanho do disco rígido, portanto, a memória virtual tem capacidade para mais armazenamento.

Reihan_amn
fonte
A memória virtual está armazenada no disco rígido dentro do arquivo / partição de troca?
BruceJohnJennerLawso
3
@BruceJohnJennerLawso: não, virtual = swap + físico
RickyA
Concordo com @RickyA, virtual> = físico sempre.
hastrb 01 de