segunda-feira, 13 de julho de 2009

Experimentos para testar os limites do sistema

Os limites do sistema podem ser levantados utilizando a função ulimit. Basta digitar ulimit para verificar os parâmetros que podem ser passados e então encontrar o valor que o sistema limita.
Os experimentos criados são para testar o quanto esses valores são seguidos, para isso foram criados alguns programas para essa análise. É importante ressaltar que os programas descritos podem trazer instabilidade para o sistema, por isso optou-se por realizar os testes numa máquina de testes (máquina virtual criada com o VirtualBox da Sun) com 512 MB de memória física.

Quantos processos podem ser criados?
Para este teste, utilizou-se a chamda fork em um loop infinito, que termina com o lançamento de uma exceção quando mais nenhum fork pode ser chamado.

#include <stdio.h>
#include <stdlib.h>

int main(){
int i=0;
while(fork()>0){
i++;
}
FILE* arquivo;
arquivo = fopen("registro","w+");
fprintf(arquivo, "Processo: %d\n", i);
fclose(arquivo);
sleep();
}
A saída para a execução deste programa foi:
Processo: 7077
O resultado foi obtido do arquivo registro após reiniciar o computador, uma vez que a execução do programa causou o travamento do computador. E o número indica, portanto, aproximadamente o número máximo de processos que podem ser criados.

Qual é o maior tamanho de processo?
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) 16382
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Qual é a maior área de heap?
A área de heap é a área que o sistema reserva para cada processo alocar memória dinamicamente, portanto o teste natural para encontrar este limite foi utilizar a chamada malloc da mesma maneira que com o fork.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MB 1024*1024

int main()
{
void *ponteiro = NULL;
int i = 0;

while(1)
{
ponteiro = (void *) malloc(MB);
if (!ponteiro) break;
memset(ponteiro,1, MB);
printf("Memória alocada: %d MB\n",++i);
}
exit(0);

}
O resultado obtido foi com a execução do programa compilado expressa o tamanho da heap:
Memória alocada: 569 MB
Killed
Esta era apresentada como ilimitada na chamada de sistema ulimit -d!

Qual é a maior área de pilha?
Toda vez que se chama uma função, o processo guarda o endereço atual na pilha e vai para o endereço da função, por isso o teste utilizado foi fazer uma função que chama a si mesma indefinidamente.
#include <stdio.h>
int i;

void funcao(){
printf("Chamada %d\n",++i);
funcao();
}

int main(){
i = 0;
funcao();
}
A execução do programa acima apresentou uma saída final:
Chamada 523826
Segmentation fault

O que significa que, se considerarmos que são 8192kB de pilha, temos que cada chamada de função armazena 16B de dados na pilha que, de fato, equivale ao tamanho do endereço.

A área de swap pode ser esgotada?
A área de swap pode ser esgotada e um dos efeitos que isso causa é o trashing da memória, isto é, os processos são retirados e recolocados na memória a ponto de mal conseguirem manter seu caminho normal de execução. Dessa maneira, o tempo de processamento aumenta muito e torna a dificulta ainda mais a liberação de memória, já que menos processos conseguem terminar sua execução.
Uma solução que foi implementada foi a utilização de swap tokens, que são uma espécie de passe para que os processos terminem sua execução e liberem espaço, evitando o trashing da memória.

Nenhum comentário:

Postar um comentário