Você lida com condições de falta de memória?

9

O que você faz quando mallocretorna uma exceção 0 ou nova de lançamentos? Basta parar ou tentar sobreviver à condição de OOM / salvar o trabalho do usuário?

mbq
fonte
4
Relacionado em Stackoverflow stackoverflow.com/questions/763159/…
ysolik
11
Argh. Eu continuo lendo isso como "fora de mana". Muitos videogames no meu passado, eu acho. :)
Adam Lear

Respostas:

4

Eu evitaria o OOM como evitar um acidente.

Evite fazer grande parte do trabalho (e alocar grande parte da memória) de uma só vez. Mantenha os dados no disco, confie no cache do disco do SO e faça uso das E / S mapeadas na memória, tanto quanto possível, e opere apenas em uma pequena parte dos dados por vez. Se grandes quantidades de dados precisarem estar on-line (servidas com baixa latência), mantenha-as na memória em várias máquinas, como fazem todas as grandes empresas de mecanismos de pesquisa. Ou compre um SSD.

rwong
fonte
Aparentemente, isso faz mais sentido.
MBq
2
Houve um grande debate sobre como lidar com OOM normalmente (RAII, segurança de exceção, blá ...), mas uma vez eu percebi isso em um sistema multithread com vários módulos dinâmicos (alguns de terceiros), mesmo se o seu thread não o fizesse. falha, há um momento de infeliz momento em que cada thread verá um OOM. Se mesmo um deles decidiu seguir em frente, você não pode fazer nada além de testemunha ocular.
Rwong 7/10
13

A maioria das pessoas que responde a essa pergunta provavelmente nunca trabalhou em sistemas embarcados, onde malloc retornando 0 é uma possibilidade muito real. Em um sistema em que estou trabalhando, há um total de 4,25 KB de RAM (4352 bytes). Estou alocando 64 bytes para a pilha e atualmente tenho um heap de 1600 bytes. Ontem mesmo eu estava depurando uma rotina de heap walk para poder seguir a alocação e a liberação de memória. O heap walk usa um pequeno buffer estaticamente alocado (30 bytes) para gerar saída para uma porta serial. Será desativado para a versão de lançamento.

Como este é um produto de consumo, é melhor não ficar sem memória depois que o produto for lançado. Tenho certeza que sim durante o desenvolvimento. De qualquer forma, tudo o que posso fazer é emitir um bipe no alto-falante algumas vezes e forçar uma reinicialização.

tcrosley
fonte
2
Montagem funcionalidades dentro de um espaço pequeno é incrível ... é uma forma de arte, como bonsai
rwong
6
Muitos projetos em sistemas embarcados simplesmente proíbem a alocação dinâmica de memória. O único caso de OOM permanece com estouro de pilha.
Mouviciel 4/10/10
Você está certo, mas especialmente com sua primeira frase: a maior parte disso simplesmente não é relevante para a maioria dos desenvolvedores por sorte.
Konrad Rudolph
4

Para ser sincero, em todos os projetos que fiz (lembre-se de que ainda não estou trabalhando em nenhum lugar), nunca considerei que isso poderia acontecer e, portanto, suponho que meus programas tenham uma morte muito rápida.

Além disso, o manuseio de uma OOM exige que você aloque previamente os recursos para exibir a mensagem de erro ou salvar tudo, o que pode ser um pouco inconveniente.

Sinto que hoje em dia, a memória custa menos que o amendoim, não é algo que deve acontecer com frequência. No início da memória protegida e antes, talvez isso fosse uma preocupação, mas agora? Os únicos erros de OOM que eu já vi foram de código com erros.

zneak
fonte
Posso pensar em recuperar parte da memória que o processo já possui e tentar sobreviver e recuperar (difícil, se você jogou algo útil) ou sobreviver como dados + restos que tentam salvá-lo.
mbq
2

A verificação dos códigos de retorno do malloc geralmente não faz sentido.

Os sistemas operacionais modernos comprometem demais a memória: eles fornecem aos processos mais memória do que realmente está disponível. A memória que seu processo recebe é virtual, mapeada para uma única página zerada.

Não é até você gravar na memória que uma página física única é alocada para seus processos. Se essa alocação falhar, o kernel encerrará um processo (talvez o seu!) Na tentativa de encontrar memória. Nesse ponto, não há mais nada que você possa fazer.

Kristof Provost
fonte
Tive uma ideia de entrar em loop while com sono prolongado por dentro - e possivelmente me recuperar se o processo sobreviver ao assassino do OOM. Tenho a impressão de que os processos foram bastante encerrados por causa de sua tentativa de usar o endereço 0, mas não fiz nenhum teste sólido.
MBq
Você não precisa fazer nada de especial para lidar com o assassino da OOM. Se seu processo o acionou, mas não foi selecionado, ele nunca saberá. Tudo funcionará como se houvesse memória suficiente. Se, por outro lado, seu processo for selecionado, ele será encerrado e também não há nada que você possa fazer.
Kristof Provost
Mas posso tentar aguardar que o OOM libere memória e tente alocar novamente e continuar. Tenho a impressão de que malloc / new não está esperando que isso aconteça.
MBq
Não, você não pode. Sua alocação sempre terá sucesso. Você obterá toda a memória virtual que desejar. Não é até você tocá-lo que a memória física é alocada. Assim que você toca em uma página não alocada, seu processo é suspenso. O kernel procurará mais memória, o que pode levar a matar um processo por mais memória. Se isso for bem-sucedido (e não prejudicar o seu!), A página será alocada e seu processo será retomado. Não há como o seu processo dizer que isso aconteceu.
9788 Kristof Provost
2
Tenho certeza de que o Windows nunca se compromete demais. Ele pode confirmar mais que a RAM, mas não mais que RAM + swapfile.
código é o seguinte
2

A menos que você esteja desenvolvendo sistemas embarcados, sistemas em tempo real ou sistemas que são tão críticos que falhas podem custar vidas ou bilhões de dólares ... Então provavelmente não vale a pena financeiramente se preocupar com as condições de falta de memória.

Na maioria dos casos, há pouco que pode ser feito quando a memória está esgotada, pois não há memória para criar novos objetos ou executar tarefas que possam fazer alguma coisa. Você precisa pesar o custo do aplicativo para lidar com o OOM versus o benefício que obtém ao fazê-lo.

Erik Funkenbusch
fonte
Os sistemas em tempo real não precisam verificar mais sobre uma falha do malloc do que os outros sistemas.
zneak
@zneak - Falso. Os sistemas em tempo real precisam ser previsíveis e a falta de memória não é previsível, a menos que você esteja planejando especificamente isso.
Erik Funkenbusch
Então, o que mais você fará quando atingir o OOM?
Zneak 4/10/10
Memória livre, cancelamento de processos, etc. Um sistema em tempo real normalmente não possui memória virtual ou sistema de troca porque precisa ser determinístico. Portanto, pode ficar mais facilmente sem memória.
Erik Funkenbusch 04/10/10
Dado um determinado caminho de código que inevitavelmente levará a um erro de OOM, não vejo como travar é uma abordagem menos determinística do que liberar memória e cancelar processos.
Zneak 4/10/10
1

Eu sempre procurava por erros. Se algo retornar uma condição de erro, ele deverá ser tratado pelo seu programa. Mesmo que seja uma mensagem que diz "Memória insuficiente, é preciso ir!", É melhor que "Violação de acesso", "núcleo despejado" ou qualquer outra coisa. Uma é uma condição de erro que você lida, a outra é um bug. E o usuário perceberá isso como tal também.

Para o seu caso específico, você pode tentar reverter a operação, liberando os recursos alocados até atingir o ponto de falha, relatando o erro e continuando a execução (talvez quando estiver tentando sair do aplicativo, você pode fornecer opção para sair imediatamente). Dessa forma, o usuário pode decidir o que fazer ou tentar liberar alguma memória, mexendo, fechando arquivos etc. É claro que a maneira como você pode lidar com a situação depende muito do seu programa - um programa que não deve ser interativo provavelmente só precisa registrar o erro e sair ou continuar.

Dysaster
fonte