Then why is the text so sure that the most recent page is moved out of RAM immediately after being accessed?
Normalmente, será a página acessada pelo menos recentemente que será expulsa, mas isso leva ao comportamento patológico descrito. Na primeira vez através do loop interno, os primeiros quadros n são paginados; então, quando a página n + 1 precisa ser paginada, a página 1 é paginada, o que garante que todas as páginas precisem ser paginadas em todas as etapas o loop.
No entanto, esse cenário é realmente improvável. Se o sistema está totalmente carente de RAM (físico e swap), o kernel irá matar um programa para liberar alguma memória; dado o comportamento do programa de teste, é improvável que seja o candidato. Se o sistema for apenas carente de RAM física, o kernel trocará páginas ou reduzirá seus caches; se trocar páginas, é improvável que ele segmente o programa de teste. Em ambos os casos, o programa de teste terá RAM suficiente para caber em seu conjunto de trabalho. Se você tentar de alguma forma privar o programa de teste apenas (por exemplo, aumentando seu conjunto de trabalho para dominar a memória do sistema), é mais provável, na prática, vê-lo ser morto com um SIGSEGV
do que você verá continuamente o seu conjunto de trabalho dentro e fora. (Isso é bom, é um experimento de pensamento em um livro de texto. Aprenda os princípios resultantes, não tente necessariamente aplicar o exemplo na prática).
Can it just keep "n-1" pages i.e. rows in RAM, and use the remaining one page for all the page faults and replacements?
poderia , mas seria incomum para o sistema fazer isso; Como o sistema saberá como serão os futuros padrões de acesso à memória? De modo geral, você verá um despejo de LRU, portanto, o loop exibirá um comportamento patológico conforme descrito acima.
Se você quiser brincar com isso, corrija o programa para que ele corresponda ao tamanho de 4KB de uma página (como usado no x86; suponho que o Linux esteja em x86 de 64 bits aqui) e, na verdade, compile:
int main(int argc, char **argv) {
int i, j;
int data[128][1024];
for (j = 0; j < 1024; j++)
for (i = 0; i < 128; i++)
data[i][j] = 0;
}
Em seguida, execute-o usando /usr/bin/time
, que mostrará o número de falhas de página:
0.00user 0.00system 0:00.00elapsed 100%CPU (0avgtext+0avgdata 1612maxresident)k
0inputs+0outputs (0major+180minor)pagefaults 0swaps
Esse tipo de manipulação de matriz causará mais problemas com despejos de linha de cache do que com falhas de página na prática.