Estou executando Fedora 26
.
Isto é para uma tarefa muito estranha dada pelo meu professor de algoritmos. A tarefa diz:
Fragmentação de memória em C:
projete, implemente e execute um programa C que faça o seguinte: Aloca memória para uma sequência de3m
matrizes com tamanho de 800.000 elementos cada; em seguida, desaloca explicitamente todas as matrizes de números pares e aloca uma sequência dem
matrizes de tamanho 900.000 elementos cada. Meça a quantidade de tempo que seu programa requer para a alocação da primeira sequência e da segunda sequência. Escolham
esgotar quase toda a memória principal disponível para o seu programa ".
O objetivo geral disso é fragmentar a memória e solicitar um pouco mais do que o que está disponível como um bloco contíguo, forçando o sistema operacional a compactar ou desfragmentar a memória.
Na aula, perguntei como deveríamos fazer isso, já que a memória é visualizada e não é realmente contígua, à qual ele respondeu: "Bem, você terá que desativar a [memória virtual]". Alguns outros alunos perguntaram na sala de aula como deveríamos saber quando atingimos essa "coleta de lixo" e ele disse que: "O tempo para a segunda alocação deve ser maior que o primeiro por causa do tempo gasto na coleta de lixo".
Depois de pesquisar um pouco, a coisa mais próxima que pude encontrar para desabilitar a memória virtual foi desabilitar a troca de memória swapoff -a
. Desativei meu ambiente de área de trabalho, compilei e executei meu programa a partir do terminal nativo (para evitar possíveis interferências de outros processos, especialmente um pesado como o Ambiente de Área de Trabalho). Fiz isso e executei meu programa aumentando m
até chegar a um ponto em que o tempo para a segunda alocação era maior que o primeiro.
Executei o programa com aumento m
e, finalmente, encontrei um ponto em que o tempo para a segunda alocação era maior que o tempo para a primeira alocação. Ao longo do caminho, porém, cheguei a um ponto em que o processo foi encerrado antes da segunda alocação. Eu verifiquei dmesg
e vi que foi morto por oom
-killer. Eu encontrei e li vários artigos sobre o oom
-killer e descobri que era possível desativar a alocação de memória excessiva pelo kernel.
Fiz isso e executei meu programa novamente, só que desta vez não consegui encontrar um m
tal que o tempo do segundo fosse maior que o primeiro. Eventualmente, com m cada vez maior (embora muito menor do que quando a alocação geral estava ativada), o malloc falharia e meu programa seria encerrado.
Eu tenho três perguntas, a primeira das quais não é realmente tão importante:
Coleta de lixo é o termo correto para isso? Meu professor é muito inflexível ao dizer que isso é coleta de lixo, mas eu assumi que a coleta de lixo era algo feito pelas linguagens de programação e que isso seria considerado mais desfragmentado.
A compactação como ele deseja é possível em um sistema Linux?
Por que consegui chegar a um ponto em que o tempo para a segunda alocação era maior que o primeiro quando desabilitei a troca, mas ainda tinha a alocação geral de memória ativada? A compactação realmente ocorreu? Se sim, por que não consegui chegar a um ponto em que a compactação ocorreu depois que desabilitei a localização geral da memória?