Question

Je suis en train de lire à propos de conditions de mémoire sur Linux, et le paragraphe suivant des pages de manuel m'a fait penser:

  

Par défaut, Linux suit une stratégie d'allocation de mémoire optimiste. Cela signifie que lorsque malloc () renvoie une valeur non NULL, il n'y a aucune garantie que la mémoire est vraiment disponible. Ceci est un bug vraiment mauvais. Dans le cas où il se trouve que le système est hors de la mémoire, un ou plusieurs processus seront tués par le tueur OOM infâme. [...]

Considérant que l'opérateur nouvelle implémentation finira par appeler malloc à un moment donné, sont-il des garanties que la nouvelle sera effectivement jeter sur Linux? S'il n'y a pas, comment peut-on gérer cette situation d'erreur apparemment indétectable?

Était-ce utile?

La solution

Cela dépend; vous pouvez configurer les paramètres de overcommit du noyau en utilisant vm.overcommit_memory.

Herb Sutter a discuté il y a quelques années comment ce comportement est en fait non conforme à la norme C ++ :

  

"Sur certains systèmes d'exploitation, y compris spécifiquement Linux, l'allocation de mémoire réussit toujours. Arrêt complet. Comment, même peut allocation toujours réussir la mémoire est vraiment pas disponible? La raison est que l'allocation elle-même enregistre simplement une demande de la mémoire;. sous les couvertures, la mémoire (physique ou virtuel) ne sont pas effectivement engagée dans le processus demandeur, avec vrai magasin de support, jusqu'à ce que la mémoire est effectivement utilisé

     

"Notez que, si de nouvelles utilise les installations du système d'exploitation directement, nouveau sera toujours réussir, mais tout code innocent plus tard comme buf [100] = « c », peut lancer ou échouer ou l'arrêt d'une norme C ++ point de vue. , les deux effets sont non conformes, parce que la norme C ++ exige que si le nouveau ne peut pas commettre suffisamment de mémoire doit échouer (cela ne), et que le code comme buf [100] = « c » ne doit pas jeter une exception ou autrement échec (cela pourrait). "

Autres conseils

Vous ne pouvez pas gérer dans votre logiciel, pure et simple.

Pour votre demande, vous recevrez un pointeur parfaitement valide. Une fois que vous allez essayer d'y accéder, il va générer une erreur de page dans le noyau, le noyau essayera d'allouer une page physique et si elle ne peut pas ... boum.

Mais comme vous le voyez, tout cela se passe à l'intérieur du noyau, votre application ne peut pas voir. Si c'est un système critique vous pouvez désactiver le surdimensionnement alltogether sur le système.

Je pense que le malloc peut encore revenir NULL. La raison pour laquelle est qu'il ya une différence entre la mémoire système (RAM + swap) et la quantité dans l'espace d'adressage de votre processus.

Par exemple, si vous demandez de 3 Go de mémoire malloc sur un linux x86 standard, il va sûrement revenir NULL car cela est impossible compte tenu de la quantité de mémoire donnée aux applications de l'espace utilisateur.

Pardonnez-moi si je me trompe, mais ne serait pas essayer de mettre à zéro la mémoire allouée suffisante pour garantir que vous avez chaque octet vous avez demandé? Ou même en train d'écrire le dernier octet, il jetterait une exception si la mémoire n'a pas été vraiment le vôtre droit?

Si cela est vrai, vous pouvez simplement essayer d'écrire à la dernière (et en premier?) Octet de la mémoire et de voir si elle fonctionne bien, et si elle ne vous pouvez pas revenir nulle de malloc.

Oui, il y a une garantie que la nouvelle finira par jeter. Quel que soit le surdimensionnement, la quantité d'espace d'adressage est limitée. Donc, si vous continuez à allouer de la mémoire, tôt ou tard vous serez à court d'espace d'adressage et de nouveaux seront obligés de jeter.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top