Esta discussão foi arquivada. Não se pode acrescentar nenhum comentário. | | | ... é uma ideia deliciosamente ingénua. E sim, eu li o artigo. O objectivo de transferir blocos de memória pouco usados da memória para a swap é libertar ram fisica para outros usos, mais imediatos. Ter o espaço de swap em ram fisica não contribui em nada para este objectivo. Apenas acrescenta problemas desnecessários. Ao criar um espaço de swap em memória, estamos a dividir a memória fisica em duas partes. Uma é, como normalmente, gerida pelo sistema e usada para várias funções: memória dos processos, buffers e caches internas. A outra, a swap, só vai ser utilizada para processos, mesmo que não esteja a ser totalmente utilizada. E a divisão vai dar origem a transferências entre os dois tipos de memória que não aconteceriam se toda a memória fisica fosse gerida normalmente.
Remember to be the Killer, not the Victim! (Nuklear Girl) |
| | | | | Pelo que entendi, tudo isto é para contornar o facto de que 1) swap em disco é mais lenta, e 2) o Linux não gosta de funcionar sem swap. Assim, consegue-se uma swap tão rápida como a memória normal. Mas, realmente, não sei até que ponto será boa ideia - talvez, porém, indique que há algumas coisas a mudar no kernel?
"It is every citizen's final duty to go into the tanks and become one with all the people." - Chairman Sheng-ji Yang, "Ethics for Tomorrow" |
| | | | O problema é que 2) é uma ideia errada. Bugs à parte, o sistema funciona perfeitamente sem swap. Agora, é boa ideia teres alguma swap, mesmo que tenhas memória suficiente para todas as tuas aplicações. Assim o kernel mete lá bocados de memória com pouco uso (e da maneira como algumas applicações são, há muito para enfiar lá), libertando assim mais memória fisica que é aproveitada para buffers e cache, o que tende a tornar o sistema mais rápido. Aliás, existe um artigo do KernelTrap, indicado num dos comentários, sobre a questão.
Remember to be the Killer, not the Victim! (Nuklear Girl) |
| | | | Em relação ao sistema de mail do Gmail, parece que eles afinal usam uma cena chamada Ysmtp feita pelo Yahoo e que é à mesma um qmail completamente kitado.
-- The worst thing about getting old, is remembering when you were young. |
| | | | Das duas uma, ou o autor do artigo não percebeu o objectivo da utilização de swap, ou o sistema de gestão de memória do linux está muito mal desenhado. A utilização de uma porção de disco para guardar segmentos de memória menos usados ou que não necessitem de estar activos tem como objectivo precisamente libertar a memória que estes segmentos ocupariam. A utilização do swap melhora o desempenho do sistema em termos de memória, mas acarreta outros problemas, nomeadamente a latência do processamento de excepções, que só é evitada desactivando o swap. Meter o swapfile em ram é uma ideia absolutamente cretina, mas pelos vistos muito popular dentro de alguns segmentos de IT desde o tempo do Windows 3.1. Sim, os segmentos dos mouse engineers e cretinos avulsos. |
| | | | | Mais ou menos... Temos alguns problemas de performance com a swap activada, para evitar que no momento que seja necessária memória extra que não está disponível o sistema "despeje" uma quantidade enorme de páginas em memória para a swap, durante o uso normal mesmo que não seja necessário, o sistema vai copiando páginas de memória menos usadas para a swap, mantendo essa cópia em memória também logo, se mais tarde for necessário memória extra, pode simplesmente apagar em páginas de memória pk já estão na swap sem gastar tempo a fazer a respectiva cópia. No entanto isto atrasa o sistema no geral pk, apesar de não ser necessário, a swap está permanentemente a ser usada. Outra coisa a ver é que as páginas de memória que estão na swap, não podem ser usadas directamente, têm de ser carregadas para a memória primeiro. Isto inadevertidamente, deu uma protecção extra que torna um sistema sem swap (já não verdade no kernel 2.6) mais frágil contra processos que usem mais memória. Se tivermos 256 Mb de ram e 512 Mb de swap, o sistema efectivamente só pode usar 256, se tivermos um processo a queimar recursos (ou que simplesmente use muitos recursos) num sistema com esta configuração os outros processos vão sendo empurrados para a swap, quando este processo atingir a barreira dos 256Mb (menos processos vitais que não vão parar à swap tipo o init) será simplesmente morto e tudo o resto recuperado com alguma lentidão é certo da swap mantendo o sistema funcional e estável (tirando, repito, a visível lentidão) no entanto, se este mesmo sistema tiver 768 de Ram, o limite de uso deste processo não é 256 mas, sim o total da memória, que pode levar a que muitos processos sejam empurrados para fora, não havendo swap para os manter, serão simplemente mortos (com o OOM killer já não presente no kernel 2.4, não é certo que o processo que morra seja o processo que consome todos estes recurso sendo o mais certos que uma série de processos ao acaso morra primeiro que este). |
| | | | Ou seja, ocorrem as 2 situações. O autor é cretino e o sistema de memória virtual está mal desenhado. A utilização de swap é um factor auxiliar, não um factor limitativo. E, como eu disse, só o facto de se possuir um sistema de swap aumenta em muito a latência de excepções (quando o cpu tenta aceder a uma page que está em swap, gera um page fault), independentemente da rapidez do dispositivo onde estão guardados os dados de swap. O sistema operativo deverá utilizar o swap sempre como último recurso e não como muleta para compensar um desenho deficiente, como ocorre com o Linux e com o Windows. |
| | | | A latência só existe se ocorrer uma excepção numa página que esteja no momento em swap exclusivamente, ou seja, senão estiver em memória e, a duração dessa latência é em relação à velocidade do dispositivo ou seja, se a swap estiver em ram, será uma latência muito curta. Em comentário ao artigo, pessoalmente achei-o muito mal escrito e, apesar de entender parte do que o autor parecia querer dizer, a forma como o expôs enterrou muito alguma verdade que tem. Pelo que entendi, se temos um sistema com mais memória que aquela que é necessária (512 para um desktop como falava) e optarmos por adicionar mais memória, qual a melhor maneira de a rentabilizar. Óbviamente, adicionar mais 1 GB de ram para swap é um desperdício inteiro mas, na verdade, manter 1.5 de ram com swap em disco torna o sistema mais lento porque, mesmo que essa swap não seja necessária, ela vai ser usada o tempo todo. O sistema vai colocar páginas em swap para o caso de vir a precisar e, sempre que a lista de processos candidatos a ir a swap mudar, mudam também as páginas a ser copiadas para swap. No entanto, apesar de com o kernel 2.4 já não haver um mapeamento directo página a página com o que está na swap logo, eliminando a necessidade de ter o dobro de swap que de memória, o sistema ainda se comporta de forma algo esquisita sem swap. A meu ver, poderia-se optar por uma de duas soluções, usar um kernel 2.4 marcar cotas de utilização de memória e criar uma pequena swap em memória como contigência (vai ser tb uma memória que vai alojar cópias de páginas de processos não incluindo cache de ficheiros e buffers em geral o que evita que estes ultimos façam pressão para que páginas menos usadas sejam empurradas para o disco e, evitar demoras no acordar de processos à muito adormecidos, pensem numa sessão de mozilla aberta à dois dias atrás). Ou simplesmente seguir com uma das ultimas versões do kernel 2.6 (apartir do 2.6.7 senão estou em erro) e mudar a swapiness a zero no kernel e desactivar toda a swap. |
| | | | numa página que esteja no momento em swap exclusivamente A alocação de swap é page-granular. Se ocorrerem frequentemente situações em que as páginas tanto existam em memória como em swap, o sistema de discard das páginas está mal concebido. Não obstante, mesmo com swap em ram, ocorreria o page fault e seria executado todo o código relativo ao gerenciamento da excepção. Claro que um acesso ao disco é sempre mais lento que um acesso a ram, mas se existisse memória suficiente para acomodar a página em ram (como existe caso o swap esteja em ram, visto que _todo_ o sistema de memória está contido em ram física), o sistema de gestão de memória virtual estaria a trabalhar "a seco". Como disse, é uma ideia absolutamente cretina. A utilização de memória virtual é (ou deveria ser) sempre último recurso e usada de forma parcimoniosa, precisamente pelo impacto que esta tem na performance global do sistema. Não há necessidade do mecanismo de gestão de memória sequer utilizar o swap caso a ram existente seja suficiente para alojar todos os segmentos alocados. O que aparentemente existe, é uma noção errada da utilidade do mecanismo de memória virtual e um abuso deste como forma de compensar uma gestão menos agressiva de memória. |
| | | | O sub-sistema VM nunca sabe quando é que vai ser necessário recorrer a memória virtual (swap), é frequente os processos alocarem mais memória que realmente usam, por exemplo ao fazer um mmap a um ficheiro de 10 MB, mesmo que só tenhas lido os primeiros 10 kbytes até ao momento (e por tanto apenas usado 10 kb, existe o potencial de a qualquer momento este processo necessitar de usar 10 Mb em ram) e como este outro exemplos existem, pelo que na realidade a qualquer momento o mais provável é existir mais memória mapeada e potencialmente vir a ser usada que aquela que realmente está a uso. Como tal, a todo o momento, páginas de memória estão a ser escritas para a swap na eventualidade de vir a ser necessário libertar memória. Se, o programa voltou a precisar desta página, não precisa de a reler da swap pk ainda se mantêm em ram a respectiva página. Se esta página foi alterada em memória e ainda se mantêm prioritária na ordem de saída, então é necessário rescrever-la para a swap. Se, entretanto outra página ganhou prioridade de saída face a esta, então outra página tem de ser escrita para a swap no lugar desta. Se, mais tarde for necessário libertar memória, como já foram escritas para a swap, basta simplesmente libertar o apontador respectivo dessa página e está pronta a ser usada por outro processo. Portanto, num sistema que tenha swap activa e mais memória que é necessária para correr as aplicações, o mais certo é todas as páginas escritas na swap manterem a cópia respectiva em memória. Por ser algo relativamente novo, o sistema ter mais memória que um grupo de programas pode utilizar, o sistema de VM tem sido concebido para maximizar a utilização da memória existente, dando a ideia a cada programa que pode utilizar toda a memória do sistema como se mais nenhum processo existisse. |
| | | | sub-sistema VM nunca sabe quando é que vai ser necessário recorrer a memória virtual (swap) Não é bem assim. O gestor de VM sabe a memória que tem disponível. é frequente os processos alocarem mais memória que realmente usam, por exemplo ao fazer um mmap a um ficheiro de 10 MB, mesmo que só tenhas lido os primeiros 10 kbytes até ao momento Não que esteja por dentro da implementação, mas presumo que o mmap use windowing. Se fosse como você afirma, um mmap de um ficheiro de 256Mb numa máquina com um total de ram+swap de 192Mb daria erro. a qualquer momento o mais provável é existir mais memória mapeada e potencialmente vir a ser usada que aquela que realmente está a uso. A um dado momento o mais provável é cada processo, aquando a janela de execução, tocar em todas as páginas alocadas. Como eu já disse, a colocação de páginas em swap deverá ser criteriosa, para evitar uma degradação de performance. Se esta página foi alterada em memória e ainda se mantêm prioritária na ordem de saída, então é necessário rescrever-la para a swap. Muitos dos gestores de memória virtual funcionam com algoritmos LRU, por isso essa situação não deveria ocorrer. Se ocorrer,uma vez mais estamos perante uma implementação deficiente Portanto, num sistema que tenha swap activa e mais memória que é necessária para correr as aplicações, o mais certo é todas as páginas escritas na swap manterem a cópia respectiva em memória. Ou seja, acabou por concordar comigo. O sistema de gestão de memória virtual está mal desenhado. ...E só um aparte... Nem toda a memória física em uso pode ser passada para swap. Qualquer página de memória que seja tocada por uma excepção (incluindo o segmento de stack) não pode ser passada para o dispositivo de memória virtual. Normalmente os Sistemas Operativos disponibilizam mecanismos para prevenir o paging do segmento especificado, por isso nada impede um processo de consumir memória sem que esta seja passada para o dispositivo de swap. |
| | | | "Não é bem assim. O gestor de VM sabe a memória que tem disponível." Sabe, não sabe é quanta vai ser usada num dado momento, se tiver 16 MB de memória e 3 processos alocarem 8Mb cada um, o sistema deixa, no entanto não existe espaço para colocar os 3, agora, entre alocar e usar vai uma grande distância. Se um processo mapear um ficheiro de 10 MB para memória, o sistema vai supor que esse processo pode gastar até 10Mb, se a leitura for linear não será necessário carregar o ficheiro todo para memória no entanto, o sistema não sabe se esse processo não irá a dado momento aceder ao ficheiro de forma aleatória obrigando todo o ficheiro a ser carregado. Básicamente, quando um processo directa ou indirectamente aloca memória, o sistema aceita esse pedido como, vou precisar de ATÉ X memória e não como, vou precisar de X memória efectivamente, apenas no decorrer do processo o sistema vai determinar quanta memória efectivamente é necessária, a maioria dos programas aloca/mapeia mais memória que aquela que realmente consome e, quando um consome mais, outro consome menos e vai trocando pelo que é possível e é o que geralmente acontece, o sistema ter mais memória mapeada do que aquela que fisicamente tem sem, no entanto, chegar a precisar de mais memória do que tem. Nestes casos (o mais vulgar, seguido do caso de não ter memória que chegue para todos os processos) haverá páginas de memória a ser copiadas para disco para o caso eventual de ser necessário libertar mais memória. "Não que esteja por dentro da implementação, mas presumo que o mmap use windowing. Se fosse como você afirma, um mmap de um ficheiro de 256Mb numa máquina com um total de ram+swap de 192Mb daria erro." Exacto, como disse atrás, um processo pode mapear mais memória que aquela que existe livre de momento (se bem que julgo que não pode alocar mais memória que aquela que existe fisicamente mas, não tenho certeza neste ponto). No entanto, pode dar-se o caso de ser necessário ter todo o ficheiro em memória simultâneamente, caso raro mas, possível, caso em que iria obrigar ao uso da swap, pelo que, mesmo que não esteja de momento a ser necessário mais espaço em memória, certas páginas vão sendo copiadas para swap para o caso de ser necessário. "A um dado momento o mais provável é cada processo, aquando a janela de execução, tocar em todas as páginas alocadas. Como eu já disse, a colocação de páginas em swap deverá ser criteriosa, para evitar uma degradação de performance." Isto é incorrecto, a maioria dos programas carrega muitas páginas que nunca chega a usar, vários exemplos, a libc, a maioria das funções podem perfeitamente nunca ser usadas e portanto certas páginas nunca serem tocadas. Um programa de edição de imagem pode carregar suporte para bmp, jpg, gif, etc... e nunca usar isso pelo que essas páginas depois de carregadas nunca seriam usadas... um programa pode ter uma função de undo ao que a cada passo que o utilizador dá são adicionadas páginas em memória que se o utilizador não usar essa função podem nunca ser tocadas até serem libertas... fazer o mapeamento de um ficheiro e não aceder a grande parte dele... um incontável número de operações que podem levar a que existam páginas em memória que depois de carregadas nunca são tocadas no decorrer da execução do programa. "Ou seja, acabou por concordar comigo. O sistema de gestão de memória virtual está mal desenhado." Não, não concordei :) Esta é a forma eficiente de usar a swap, o sistema não tem condições de adivinhar a utilização possível de memória por parte do utilizador e tem de manter várias hipóteses em aberto, para evitar isto podemos sempre desactivar a swap no entanto, estamos cientes que quando faltar memória o sistema bloqueia forte e feio. E, difícilmente coloca mais memória num computador do que ele pode utilizar no pior cenário pelos diversos factores expostos acima e outros posts. "(...)por isso nada impede um processo de consumir memória sem que esta seja passada para o dispositivo de swap." Impede. O facto de ALGUMA memória não poder ir parar à swap não serve para dizer que é possível um processo alocar TODA a sua memória dessa forma, o código que faz o processo o que ele é, fica alojado em páginas que podem ir parar à swap, pelo que pelo menos essa parte da memória que compõe o processo pode ir parar à swap. |
| | | | Perdão por responder a mim mesmo mas, li mal este teu comentário e acabei por responder uma coisa totalmente diferente... "Não que esteja por dentro da implementação, mas presumo que o mmap use windowing. Se fosse como você afirma, um mmap de um ficheiro de 256Mb numa máquina com um total de ram+swap de 192Mb daria erro." Sim, dá erro... podes abrir e ler o conteúdo de um ficheiro maior do que tens espaço em memória mas, não podes mapear um ficheiro maior que o total de espaço livre.
|
| | | | Não é assim tão linear. No kernel 2.0 e no 2.2, isso era possível, o kernel usava um sistema esquizo de windowing. Aparentemente no 2.4 isso já não funciona, apesar do mmap retornar operação bem sucedida. O facto do mmap fazer um mapeamento para endereços virtuais não quer dizer que o objecto mmapped tenha que estar totalmente carregado em memória. Claro que isso também varia de implementação para implementação, e do espaço de endereçamento virtual existente. |
| | | | Hum ? O ficheiro fica mapeado no espaço do processo e é "lido" via o esquema normal de VM. O "total de espaço livre" é 1G ou 2G ou 3G ou uma quantidade astronomica conforme a plataforma/kernel. |
| | | | Humm isso não está necessariamente errado, mas também não está necessariamente correcto. Os gastos de memória com um dado processo provêm de duas vias: Mapeamento dos diversos segmentos do executável na memória. Isto inclui a alocação dos dois segmentos de dados onde residem as variáveis globais e estáticas (.BSS e .DATA), e o segmento de stack, onde normalmente residem as variáveis locais e os parâmetros passados a funções. Se o sistema operativo não conseguir alocar a memória mínima necessária, o processo nem sequer é iniciado. Cada vez que o processo invoca fork(), é gerado um span do processo com uma cópia integral do conteúdo dos diversos segmentos. Alocação de variáveis dinâmicas, ou mapeamento de recursos. Esta é a parte complicada. O sistema operativo não assume nada no que toca à utilização de memória por um dado processo. A alocação de memória é feita em termos de espaço de endereçamento virtual (endereçamento linear). Não interessa se os endereços virtuais estão ou não presentes em ram. O CPU transforma os endereços virtuais em endereços físicos recorrendo ao mecanismo de paging. Do ponto de vista aplicacional, existem inúmeras formas de alocar memória. Normalmente os programas feitos em C usam as rotinas base da libc para proceder à alocação de blocos, com a grande vantagem que não são page-granular. A própria implementação do malloc() e a forma como é alocado o espaço de heap inicial libc varia de sistema para sistema. O que interessa é que o programa, quando tenta alocar um bloco de memória, gera uma de 3 situações possíveis: A alocação é bem sucedida, o programa continua a execução normal; As rotinas internas da libc verificam que não conseguem atender ao pedido, não existem blocos livres suficientes. Um comportamento possível é requerer ao sistema operativo um aumento da área já alocada. Caso isto ocorra, e exista uma situação de falta de ram, é possivel ao kernel meter o processo em SLEEP até que exista memória suficiente para responder ao pedido. Em caso afirmativo, a alocação é bem sucedida. O mecanismo de alocação não faz redimensionamento de segmentos, ou não conseguiu redimensionar o segmento alocado. A alocação falha. No caso de falha da alocação, é da responsabilidade da aplicação gerir o problema. Se tiveres 16Mb de ram, sem swap, o sistema não te vai permitir a alocação de 3 blocos de 8Mb porque não possui espaço de endereçamento linear disponível. Isto é incorrecto, a maioria dos programas carrega muitas páginas que nunca chega a usar, vários exemplos, a libc, a maioria das funções podem perfeitamente nunca ser usadas e portanto certas páginas nunca serem tocadas. Isso também não é linear. Se a linkagem da aplicação for estática, o código de todas as funções usadas é embebido na aplicação. Não é embebida a libc completa, mas os diferentes object files necessários contidos na libc. Se a linkagem for dinâmica, ocorre o que disse. No entanto, o objecto carregado é partilhado por todos os processos que o usam, e o alinhamento dos símbolos não é feito em páginas. Embora possa ocorrer existirem páginas pertencentes à libc que sejam passadas para swap, representa sempre apenas uma fracção do espaço alocado. um incontável número de operações que podem levar a que existam páginas em memória que depois de carregadas nunca são tocadas no decorrer da execução do programa. Sem dúvida, mas ao sistema operativo compete fazer o tradeoff entre memória disponível e memória virtual, e não ensinar o programador da aplicação a programar. É muito simples encravar qualquer sistema operativo comendo ram, independentemente do mecanismo de gestão de memória usado. Esta é a forma eficiente de usar a swap, o sistema não tem condições de adivinhar a utilização possível de memória por parte do utilizador e tem de manter várias hipóteses em aberto Não se a utilização de swap vier com uma degradação de performance visível. Por exemplo, em BSD, é normal o sistema começar a usar o espaço de swap apenas quando ocorre uma diminuição drástica da memória física disponível. É o melhor exemplo de gerenciamento de memória virtual que conheço. O facto de usar menos swap diminui a latência de excepções, maximiza a utilização do dispositivo onde reside o swap, e evita concorrência desnecessária ao acesso ao dispositivo. No caso das drives IDE/ATA, sem dúvida que contribui para diminuir o desgaste da própria drive em si. Impede. O facto de ALGUMA memória não poder ir parar à swap não serve para dizer que é possível um processo alocar TODA a sua memória dessa forma É possível. Basta usar mlockall() ou o syscall com o mesmo nome, apesar de só ser possível se o processo correr como super-utilizador. |
| | | | A ideia que quis passar é que existem inúmeros mecanismos que fazem com que a memória que os processos pedem directa ou indirectamente seja sempre maior e por vezes muito maior do que aquela que realmente usam, dando a ideia ao sistema que a dado momento será possível vir a precisar de mais memória e, aqui não existe solução perfeita. Ou se vai copiando páginas para swap pouco a pouco por forma a não ser aparente na performance que se está a usar swap ou então, quando for necessário irá ocorrer uma tempestado para despejar inúmeras páginas. O kernel 2.4 opta pela primeira opção com o grau de antecipação de escrita já definido, no kernel 2.6 é possível configurar o grau de agressividade com que as páginas vão sendo copiadas até ter swapiness a zero ou seja, não copia nada para swap até ser necessário (segundo caso falado). Se optarmos como muita gente, por desactivar a swap, estamos a operar segundo a ideia que os processos vão operar bem sem a swap mas, isso é uma coisa que só nós podemos ver e, se acontecer um caso raro, os processos simplesmente blocam. |
| | | | > isso é uma coisa que só nós podemos ver e, se acontecer um caso raro, os processos simplesmente blocam. Que caso raro ? Acabar a memória ? Ai entra o OOM killer e dá cabo do openoffice! :) |
| | | | > Cada vez que o processo invoca fork(), é gerado um span do processo com uma cópia integral do conteúdo dos diversos segmentos. Não. As páginas são remapeadas COW. É um truque engraçado :) Os dois pontos do text e data dão a entender que a alocação é feita de maneira diferente. Não é. > Do ponto de vista aplicacional, existem inúmeras formas de alocar memória. Não, do ponto de vista de user space existe uma maneira de alocar memória, o brk() (ou equivalente) que aumenta o espaço virtual do processo. O mmap não aumenta no sentido de alocar memória. A libc tem um gestor de memória que esconde isto e apresenta o malloc()/free() standard em C. Sobre a gestão de memória e userspace, o discurso implica que não há overcommit e está a falar de uma VM que parece mais de um OS tempo real para 286 do que a VM do kernel. > Não é embebida a libc completa, mas os diferentes object files necessários contidos na libc. :) Isso bem bonito mas na vida real, não. Além disso mesmo que seja um executavel estático é carregado da mesma maneira que um dinamico do ponto de vista da VM. > Por exemplo, em BSD, Qual BSD ? > começar a usar o espaço de swap apenas quando ocorre uma diminuição drástica da memória física disponível. Ie. não usa sempre a memória a 100% ? Ou não aloca buffers para não mexer na swap ? Parece-me uma história mal contada. > É o melhor exemplo de gerenciamento de memória virtual que conheço. A descrição parece-me um bocadinho básica para ficarmos a conhecer também. |
| | | | Não. As páginas são remapeadas COW. Sim, é verdade. Não é criada uma cópia integral da imagem do processo inicial, é efectuado um remapeamento das páginas do novo processo. O erro foi meu. Não, do ponto de vista de user space existe uma maneira de alocar memória, o brk() (ou equivalente) que aumenta o espaço virtual do processo. O mmap não aumenta no sentido de alocar memória. A libc tem um gestor de memória que esconde isto e apresenta o malloc()/free() standard em C. Se der uma olhada no código do malloc, verá que o malloc implementa os dois métodos. Mas sim, por defeito usa o sbrk(). Sobre a gestão de memória e userspace, o discurso implica que não há overcommit e está a falar de uma VM que parece mais de um OS tempo real para 286 do que a VM do kernel Implica porquê? Nenhum dos mecanismos da VM do kernel do Linux implica sequer a existência de swap ou de dispositivo de swap. Da mesma forma, nem todos os sistemas de swap se baseiam num sistema de endereçamento virtual. O endereçamento virtual e o mecanismo de swap são duas realidades distintas, apesar de serem implementadas em conjunto. O overcommit assenta sobre o mecanismo de endereçamento virtual, não sobre o mecanismo de swap. E um RTOS tem exigências essencialmente sobre o scheduler, não sobre o gestor de memória. :) Isso bem bonito mas na vida real, não. No caso da libc, sim. O código está fragmentado o suficiente para aquando a linkagem só serem usados os ficheiros-objecto necessários. Além disso mesmo que seja um executavel estático é carregado da mesma maneira que um dinamico do ponto de vista da VM. Não necessariamente. Um executável de 10kb com uma dependência dinâmica de 1000kb ocupa mais memória que um executável de 1010Kb. Qual BSD ? Em qual deles é que a situação que descrevi não ocorre? Apesar dos 3 BSD's mais conhecidos terem um mecanismo de VM significativamente diferente, em todos eles se nota uma menor dependência de swap. Ie. não usa sempre a memória a 100% ? Ou não aloca buffers para não mexer na swap ? Parece-me uma história mal contada. O swap só é usado quando é preciso. Caso deseje conhecer melhor a implementação, sugiro uma leitura cuidada do texto contido no seguinte link. A descrição parece-me um bocadinho básica para ficarmos a conhecer também. Vide link fornecido acima. Para um informático, afigura-se parco de capacidades no que toca a descobrir a informação que quer. Deve ser do swap... |
| | | | > Se der uma olhada no código do malloc, verá que o malloc implementa os dois métodos. Dois metodos ? Quer dizer o brk e o mmap ou o brk e o sbrk ? Sem olhar tenho a certeza quase absoluta que o malloc da glibc nunca toca no mmap. Sobre os comentários da VM, os 3 casos e a linguagem (segmentos ?) são tipicos de um RTOS (SLEEP ?) para 286, dos vários que apareceram. Ao contrário dos RTOS, é bastante provável que um malloc() superior ao espaço livre não dê erro em Linux (não confundir com outras coisas como DU que não fazem overcommit default) dado que o mapeamento de paginas não causa page faults. O que acontece é que a zero page (uma página especial cheia de zeros) é mapeada no espaço do processo em modo COW. Uma alocação só falha quando o processo chega ao limite do virtual size (rlimit ou limite da arquitectura). Isto é incrivelmente útil porque permite alocar arrays esparsos sem recorrer a mmap de ficheiros esparsos. Quando é a página é escrita ai sim ocorre um page fault e pode ocorrer uma situação de OOM (por isso é que o código de resolução de OOM é complicado). > No caso da libc, sim. O código está fragmentado o suficiente para aquando a linkagem só serem usados os ficheiros-objecto necessários. Nem era a isso que me referia, era mais aos casos de aplicações estaticas tipicas (Netscape+Motif etc) em que a lib está lá toda. No caso de glibc/gcc é preciso explicar ao ld o que queremos :) > Não necessariamente. Um executável de 10kb com uma dependência dinâmica de 1000kb ocupa mais memória que um executável de 1010Kb. Mais ou menos, depende do ld.so mas de novo não me expliquei bem. Queria dizer que são os dois paginados exactamente da mesma maneira pela VM e em ambos os casos o peso morto é chutado para swap. > O swap só é usado quando é preciso. Caso deseje conhecer melhor a implementação, sugiro uma leitura cuidada do texto contido no seguinte link. Ah sim :) O documento do Matt Dillon. A parte 2. descreve uma VM generica UNIX e faz parece que é mais ou menos mágica enquanto que o 386 faz 95% do trabalho, mas é uma boa descrição do problema. Há maneiras engraçadas de resolver o problema da paginação de executaveis como por exmplo mapea-las ro public e altera-las para páginas rw private quando o processo provoca um fault, que é o que a VM do Linux faz. Assim não é necessário manter a lista de páginas mortas. Na realidade, acho que os BSD recentes também fazem isto. A parte 3. pode tão fácilmente descrever o swap de fbsd como de linux, como é indicado on último paragrafo. Todos os 'truques' são usado em linux também, a grande diferença está nos algoritmos usados. Entre o 2.2 e o 2.4 houveram grandes alterações, avanços e recuos, nestes algoritmos. Bem analisado, no último paragrafo o Matt contrari a tudo o que o Ancestor disse até agora, o fbsd não usa menos a swap, usa *mais* e por isso porta-se melhor que o linux em situações de falta de memória. Este artigo é um bocadinho antigo, isto era verdade até ao fimzinho do 2.3 que era famosos pelos "swap storms" em que o kernel tinha o low watermark muito baixo e não era suficientemente agressivo a reclamar páginas. No 2.4 isto já não é assim e o kernel é bastanto mais proactivo a pre cachear páginas em swap como o Myke já descreveu. A grande vantagem que o Matt refere, o scater gather O(1), é uma coisa que está a ser introduziada no 2.6 mas que não tem nada a ver com a utilização de swap. Tem a ver com a performance de aplicações mais gulosas como o Oracle. Também é interessante a afirmação de que remapear páginas sai quase de borla. É verdade no contexto do gestor de VM mas na prática depende muito da arquitectura em que está a correr. Na parte 5. está explicado aquilo que eu disse sobre malloc e OOM. De memória diria que ambos os problemas expostos na parte 6. estão bastante melhor tanto no linux 2.6 como no fbsd 5 mas não me comprometo :) Tenho quase a certeza que os code path O(n^2) já desapareceram no 2.6, ficando O(n) (ou "simply iterate" :)) Cuidado finalmente que este documento é escrito para pessoas de CS, algumas partes podem ser enganadoras para pessoas que não dominam totalmente a linguagem. Defeito de uma pessoa que como o Matt é extremamente cromo de VM ;) |
| | | | Já agora, convem acrescentar que o Matt Dillon foi escorraçado do FreeBSD por criticar abertamente o modelo de smp do fbsd5 e está a desenvolver um fork do fbsd4 qualquer coisa. |
| | | | Escorraçado é um termo forte, e o nome do fork é DragonFlyBSD. Além disso, as contribuições de código do Matt Dillon não abarcam só o FreeBSD. |
| | | | Pronto ok, não foi escorraçado, descobriu que já não tinha previlegio de escrita no repositorio quando tentou fazer um commit. |
| | | | A parte 2. descreve uma VM generica UNIX e faz parece que é mais ou menos mágica enquanto que o 386 faz 95% do trabalho, mas é uma boa descrição do problema. Bem pelo contrário. A VM do linux assenta directamente no mecanismo de paging do CPU. No caso do FreeBSD, são usadas estruturas de controlo independentes da arquitectura, e só posteriormente as áreas definidas por essas estruturas são mapeadas no mecanismo de paging. A parte 3. pode tão fácilmente descrever o swap de fbsd como de linux, como é indicado on último paragrafo. Todos os 'truques' são usado em linux também, a grande diferença está nos algoritmos usados. Entre o 2.2 e o 2.4 houveram grandes alterações, avanços e recuos, nestes algoritmos. Na parte 3 são descritos dois métodos. Qual deles pode ser aplicado ao Linux? De referir que, pelo menos no 2.4, o algoritmo usado é similar a uma lista LRU. O que o FreeBSD 4 usa é com uma hash table. Além disso, o algoritmo de selecção de páginas a serem passadas para swap é significativamente diferente. Além do mais, no último parágrafo diz explicitamente que o sistema tende a usar swap quando está com falta de memória. Ora, isso seria o comportamento correcto, não? Como eu afirmei algures, a utilização do swap deve ser criteriosa. Quanto à idade do artigo, aplica-se ao branch -STABLE do FreeBSD, que ainda é 4.X. Na parte 5. está explicado aquilo que eu disse sobre malloc e OOM. Não devemos ter lido a mesma parte 5. O que lá refere é o mecanismo de COW do FreeBSD e a abordagem conseguida para minimizar o impacto causado pelos pedidos de zero-filled pages. De memória diria que ambos os problemas expostos na parte 6. estão bastante melhor tanto no linux 2.6 como no fbsd 5 mas não me comprometo :) Tenho quase a certeza que os code path O(n^2) já desapareceram no 2.6, ficando O(n) (ou "simply iterate" :)) (...)FreeBSD tends to make better choices on which pages to reuse or swap when memory is stressed, giving it better performance under load(...) Parece que afinal o autor do artigo também concorda comigo. Apesar de realmente haverem diferenças significativas quer no Linux 2.6, quer no FreeBSD 5, não retira veracidade ao que afirmei. E teoria à parte, se realmente usar *BSD, nota perfeitamente que a utilização de swap é muito inferior ao verificada em linux. Cuidado finalmente que este documento é escrito para pessoas de CS Na realidade esse é um artigo introdutório, e quase não fala do sistema de LOM do FreeBSD, que é onde reside uma significativa parte do engenho (e da complexidade). E, sem dúvida, o Sr Matt Dillon é um cromo da VM e não só. |
| | | | > Bem pelo contrário. A VM do linux assenta directamente no mecanismo de paging do CPU. No caso do FreeBSD, são usadas estruturas de controlo independentes da arquitectura, e só posteriormente as áreas definidas por essas estruturas são mapeadas no mecanismo de paging. Isto quer dizer que teem uma abstração que é implementada em cada uma das arquitecturas ou que teem mais um nivel de indireção ? > Na parte 3 são descritos dois métodos. Ops! Onde eu escrevi parte 3 queria dizer 4! Como está o que escrevi não faz muito sentido. De qualquer modo, o que ele descreve para o fbsd3 é o mesmo q o linux usava no fim do 2.3/ inicio do 2.4. O que é descrito para o fbsd4 é semelhante ao 2.6 (e talvez ao 2.4 actual, não sei ao certo como estão as coisas). > Não devemos ter lido a mesma parte 5. O que lá refere é o mecanismo de COW do FreeBSD e a abordagem conseguida para minimizar o impacto causado pelos pedidos de zero-filled pages. "The BSS area is expected to be initially zero but the VM system does not bother to allocate any memory at all until the process actually accesses it. When a fault occurs the VM system must not only allocate a new page, it must zero it as well." - Matt versus "O mecanismo de alocação não faz redimensionamento de segmentos, ou não conseguiu redimensionar o segmento alocado. A alocação falha. No caso de falha da alocação, é da responsabilidade da aplicação gerir o problema. Se tiveres 16Mb de ram, sem swap, o sistema não te vai permitir a alocação de 3 blocos de 8Mb porque não possui espaço de endereçamento linear disponível." - Ancient Um de vocês está errado e eu já me puz do lado do Matt :) > Parece que afinal o autor do artigo também concorda comigo. Parece que afinal o autor do artigo está a defender o codigo que escreveu. Não defende mal nem mente mas afirmações qualitativas devem ser interpretadas no contexto em que são ditas.
> se realmente usar *BSD, nota perfeitamente que a utilização de swap é muito inferior ao verificada em linux. O Matt diz exactamente o contrário, e tem razão pelo menos para fbsd4 vs linux2.4. Em funcionamento normal o fbsd tem mais clean pages duplicadas em swap. O 2.6 e o 2.4-rmap teem resultados semelhantes ao fbsd segundo me dizem. É claro que para verificar isto é preciso as ferramentas certas. O fbsd em funcionamento normal mostra menos swap utilizada do que o linux no free porque o metodo de gestão é diferente. Enquanto que o fbsd as mostra como in core (apesar de estarem a ocupar swap) o linux mostra-as swaped apesar de estarem in core marcadas como clean e com maps anonimos. > Na realidade esse é um artigo introdutório, Eu referia-me aos usos de "O(1)", "simply iterate" que podem passar a ideia errada a quem não sabe o que os termos escondem. |
| | | | Isto quer dizer que teem uma abstração que é implementada em cada uma das arquitecturas ou que teem mais um nivel de indireção ? Quer dizer que são diferentes, inclusive até por razões históricas. Quanto ao pedaço que transcreveu, estava no contexto de malloc e não de mapeamento do binário. E, como referi, o malloc pode usar sbrk ou mmap. O Matt diz exactamente o contrário, e tem razão pelo menos para fbsd4 vs linux2.4. Em funcionamento normal o fbsd tem mais clean pages duplicadas em swap Diz? Em que parágrafo exactamente? Há uma diferença entre ter o swap mapeado e ter páginas em swap. E de facto o FreeBSD usa menos o mecanismo de swap que o linux, precisamente porque implementa um algoritmo diferente. Não é dificil de constatar isso. Mas pronto, cada um é como cada qual, e realmente se acha que não, respeito a sua opinião. |
| | | | > Se ocorrerem frequentemente situações em que as páginas tanto existam em memória como em swap, o sistema de discard das páginas está mal concebido. Não > A utilização de memória virtual é (ou deveria ser) sempre último recurso e usada de forma parcimoniosa, precisamente pelo impacto que esta tem na performance global do sistema. Modo real ? não me parece. |
| | | | Swap em RAM é sempre inutil. A analise inicial que é particionar a memória numa parte viva e numa parte morta está correcta. É melhor não usar swap de todo e as páginas não usadas ir ficando em ... ram :) (btw, se há memória a mais mais vale meter lá a /tmp) |
| | | | | Parece-me que estás a pensar no VM dos primeiros kernel 2.4.x, em que se tivesses X MB de RAM, necessitavas de X+Y MB de swap para ter um total de X+Y MB disponiveis. Ou estou enganado? Remember to be the Killer, not the Victim! (Nuklear Girl) |
| | | | A questão da swap ser maior que a memória disponível é de ter espaço para em caso de um processo gastar toda a memória disponível, haver espaço para acomodar os demais até este ser morto. Caso contrário, quando a swap encher, ainda haverá processos em memória e o sistema irá começar a matar algum e, até acertar no processo que está a causar estragos outros podem perder-se. De lembrar que o kernel 2.4 não possui um mecanismo de selecção de qual o processo mais provavel de estar em falta para morrer (OOM killer). |
| | | | Ah, agora percebi-te. Por acaso, o OOM Killer do 2.4 tinha um mecanismo de selecção: matar o processo que consumia mais memória. Só que tendia a ser uma escolha infeliz..
Remember to be the Killer, not the Victim! (Nuklear Girl) |
| | | | O OOM Killer veio do tempo do 2.2 foi alterado por diversas vezes durante meses a fio e quando chegou o 2.4 (que inicialmente tinha) foi simplesmente retirado. O problema essencial é que muitos processos alocam recursos através de terceiros no caso de programas gráficos que alocam em nome do X. E outros têm por erro, recursos "perdidos" que como não têm dono, pertencem ao processo inicial (init) pelo que os primeiros processos a morrer acabavam por ser o X e o init. Que digamos, não era nada bom para o sistema :) |
| | | | Se bem me lembro o OOM nunca entrou no 2.2, no 2.4 existe (default off) e no 2.6 exite também. No 2.4 existiram vários OOM killer, pelo menos dois Rik e 1 do Andrea. O método foi sendo variado em mais memoria alocada, mais memória in core, o desgraçado que está a alocar agora e umas coisas engraçadas que envolviam "o mais comilão nos últimos X minutos". |
| |
|