Pergunta

Eu tenho lido sobre as condições fora da memória no Linux, e o parágrafo a seguir das páginas do homem me fez pensar:

Por padrão, o Linux segue uma estratégia de alocação de memória otimista. Isso significa que, quando Malloc () retorna não-nulo, não há garantia de que a memória realmente esteja disponível. Este é um bug muito ruim. Caso o sistema esteja fora de memória, um ou mais processos serão mortos pelo infame assassino de OOM. [...

Considerando que a nova implementação do operador acabará ligando para Malloc em algum momento, há alguma garantia de que o novo lançará o Linux? Se não houver, como lida com essa situação de erro aparentemente indetectável?

Foi útil?

Solução

Depende; Você pode definir as configurações de compensação excessiva do kernel usando vm.overCommit_memory.

Herb Sutter discutiu há alguns anos como Esse comportamento é realmente não conforme o padrão C ++:

"Em alguns sistemas operacionais, incluindo especificamente o Linux, a alocação de memória sempre é bem -sucedida. Parada completa. Como a alocação pode sempre ter sucesso, mesmo quando a memória solicitada realmente não está disponível? O motivo é que a alocação em si apenas registra uma solicitação para a memória; Sob as capas, a memória (física ou virtual) não está realmente comprometida com o processo de solicitação, com o Real Backing Store, até que a memória seja realmente usada.

"Observe que, se o New usar as instalações do sistema operacional diretamente, o novo sempre terá sucesso, mas qualquer código inocente posterior como BUF [100] = 'C'; pode jogar ou falhar ou parar. De um ponto de vista padrão C ++, ambos os efeitos são não conforme, porque o padrão C ++ exige que, se o novo não puder comprometer a memória suficiente, ele deve falhar (isso não), e esse código como BUF [100] = 'C' não deve jogar uma exceção ou falhar (isso poderia)."

Outras dicas

You can't handle it in your software, pure and simple.

For your application you will receive a perfectly valid pointer. Once you will try to access it, it will generate a page fault in the kernel, the kernel will try to allocate a physical page for it and if it can't ... boom.

But as you see, all this happens inside the kernel, your application cannot see that. If it's a critical system you can disable the overcommit alltogether on the system.

I think the malloc can still return NULL. The reason why is that there is a difference between the system memory available (RAM + swap) and the amount in your process's address space.

For example, if you ask for 3GB of memory from malloc on a standard x86 linux, it will surely return NULL since this is impossible given the amount of memory given to user space apps.

Forgive me if I'm wrong, but wouldn't trying to zero out the memory allocated be enough to guarantee that you have every single byte you requested? Or even just writing to the last byte, it would throw an exception if the memory wasn't really yours right?

If that's true, you could just try writing to the last (and first?) byte of the memory and see if it works fine, and if it doesn't you could return null from malloc.

Yes, there is one guarantee that new will eventually throw. Regardless of overcommit, the amount of address space is limited. So if you keep allocating memory, sooner or later you will run out of address space and new will be forced to throw.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top