Programas de memória que bloqueiam o sistema

3

Eu tenho o seguinte problema: um programa tem um bug como o seguinte

int main() {
  for(;;) {
    char *p = (char*)std::malloc(1024);
    std::memset(p, 1, 1024);
  }
}

E ele continua alocando memória até o meu sistema começar a trocar páginas de outros aplicativos em favor desse programa e não posso fazer mais nada na caixa. Eu bati este problema várias vezes com diferentes aplicativos (hoje, foi com o moonlight 2 beta no firefox). Eu acho que o problema é porque o programa faz com que a memória de outro programa seja trocada, e assim ele poderia usar mais memória física.

Naturalmente, olhei para o ulimit e encontrei duas configurações

-m the maximum resident set size
-v the size of virtual memory

Eu li que o primeiro denota o tamanho total da memória física que o processo pode usar de uma só vez. Para mim, parece que isso é mais sensato do que o tamanho total da memória virtual, porque pode ser compartilhado, e pode não ter importância nenhuma, porque foi trocado de qualquer maneira. Então, eu adicionei o seguinte ao meu .bashrc depois de olhar para os tamanhos habituais de conjuntos de residentes com top , que variam em torno de 120MB para uma sessão normal do firefox, eu encontrei.

# limit usage to 256MB physical memory out of 1GB
ulimit -m 262144

Mas depois de executar o snippet de teste acima, ele ainda diminuiu meu sistema, e eu tive que esperar cerca de 5 minutos até que o terminal reconhecesse minhas teclas ^C . Normalmente, se eu não reajo nos primeiros segundos, nessas situações eu só posso pressionar o botão de reset, o que eu realmente não gosto - alguém tem uma estratégia de como resolver isso? Por que o trabalho físico não limita? Parece-me que desta forma, outras aplicações ainda devem ter memória física suficiente para reagir de forma sensata.

    
por Johannes Schaub - litb 02.10.2009 / 21:05

3 respostas

1

Você tentou usar o sinal -v ?

O conjunto de trabalho residente é definido pela quantidade máxima de memória mantida como um conjunto de trabalho na RAM antes da troca. Portanto, não limitará a quantidade total de partes trocadas de memória do conjunto de trabalho. O -v sinalizador deve fazer o trabalho.

VIRTUAL MEMORY SIZE: o mais útil das limitações relacionadas à memória, porque inclui todos os tipos de memória, incluindo os arquivos stack, heap e memory-mapped. As tentativas de alocar memória além desse limite falharão com um erro de falta de memória.

É bastante surpreendente que os recursos na rede descrevendo isso em profundidade não sejam realmente fáceis de encontrar! Eu fiz o experimento na minha caixa linux.

Ele pára com exceção de

  ulimit -v 100000

e não com o sinalizador -m . A única coisa que me surpreendeu foi a exceção:

segmentation fault

Eu teria esperado out of memory .

    
por 02.10.2009 / 21:52
1

Acho que a implementação ulimit é uma droga aleatória em quase todos os sistemas operacionais. Eu tenho usado o ulimit -S -v no Linux por seis anos. Seis! E parece que alguns kernels não estão mais suportando isso. Eu tenho um Mac e OS X 10.6 não está suportando isso. Eu também tentei com -m. Na minha antiga área de trabalho com o Ubuntu 9.04, ulimit -S -v funciona bem.

Na verdade, estou procurando uma solução real para isso. Eu simplesmente não consigo acreditar que as pessoas da Apple, por exemplo, permitem que o seu programa fique cheio de memória.

    
por 18.07.2010 / 07:21
0

Vazamento de memória clássico. Eu tenho medo, você precisa corrigir a aplicação em questão, não há muito o sistema operacional pode fazer. Tudo o que o sistema operacional poderia fazer é restringir a memória para um aplicativo, mas o aplicativo em questão iria travar / segfault e talvez levar o sistema operacional ou pelo menos o xorg com ele.

Você poderia ld_preload outra versão do malloc e adicionar um thread para liberá-lo após uma quantidade especificada de segundos. Eu duvido que isso funcione, embora ...

Você precisaria desse tut: link

    
por 21.02.2010 / 13:14

Tags