Comment puis-je allouer de la mémoire sous Linux sans surengagement
C'est une question chargée, ou du moins incorrecte. La question est basée sur une hypothèse incorrecte, ce qui rend la réponse à la question posée au mieux non pertinente, au pire trompeuse.
La surallocation de mémoire est une politique à l'échelle du système, car elle détermine la quantité de mémoire virtuelle mise à la disposition des processus, et non quelque chose qu'un processus peut décider lui-même.
Il appartient à l'administrateur système de déterminer si la mémoire est surchargée ou non. Sous Linux, la politique est tout à fait réglable (voir par exemple /proc/sys/vm/overcommit_memory
chez l'homme 5 proc. Il n'y a rien qu'un processus puisse faire pendant l'allocation qui affecterait la politique de surcharge de la mémoire .
OP semble également intéressé à rendre leurs processus immunisés contre le tueur de mémoire insuffisante (OOM killer) sous Linux. (OOM killer sous Linux est une technique utilisée pour soulager la pression de la mémoire en tuant les processus et en libérant ainsi leurs ressources vers le système.)
Cette approche est également incorrecte, car le tueur de MOO est un processus heuristique, dont le but n'est pas de "punir ou de tuer les processus qui se comportent mal", mais de maintenir le système opérationnel. Cette fonctionnalité est également tout à fait réglable sous Linux, et l'administrateur système peut même régler la probabilité que chaque processus soit tué dans des situations de forte pression de la mémoire. Outre la quantité de mémoire utilisée par un processus, il n'appartient pas au processus d'affecter si le tueur de MOO le tuera lors de situations de mémoire insuffisante; il s'agit également d'un problème de stratégie géré par l'administrateur système, et non par les processus eux-mêmes.
J'ai supposé que la question réelle que l'OP essaie de résoudre est de savoir comment écrire des applications ou des services Linux capables de répondre dynamiquement à la pression de la mémoire, autre que de simplement mourir (à cause de SIGSEGV ou du tueur OOM). La réponse à cela est vous ne le faites pas -- vous laissez l'administrateur système s'inquiéter de ce qui est important pour eux, dans la charge de travail qu'ils ont, à la place --, à moins que votre application ou service n'utilise beaucoup de mémoire, et qu'il soit donc susceptible d'être injustement tué pendant une mémoire élevée pression. (Surtout si l'ensemble de données est suffisamment volumineux pour nécessiter l'activation d'une quantité de swap beaucoup plus importante que celle qui serait autrement activée, ce qui entraîne un risque plus élevé de tempête de swap et de tueur de MOO tardif mais trop puissant.)
La solution, ou du moins l'approche qui fonctionne, consiste à verrouiller en mémoire les parties critiques (ou même l'ensemble de l'application/du service, s'il fonctionne sur des données sensibles qui ne doivent pas être échangées sur disque), ou d'utiliser une carte mémoire avec un fichier de sauvegarde dédié. (Pour ce dernier, voici un exemple que j'ai écrit en 2011, qui manipule un ensemble de données de la taille d'un téraoctet.)
Le tueur OOM peut toujours tuer le processus, et un SIGSEGV se produit toujours (en raison, par exemple, d'une allocation interne par une fonction de bibliothèque à laquelle le noyau ne parvient pas à fournir une sauvegarde RAM), à moins que toute l'application ne soit verrouillée sur RAM, mais au moins le le service/processus n'est plus injuste ciblé, simplement parce qu'il utilise beaucoup de mémoire.
Il est possible d'attraper le signal SIGSEGV (qui se produit lorsqu'il n'y a pas de mémoire disponible pour sauvegarder la mémoire virtuelle), mais jusqu'à présent, je n'ai pas vu de cas d'utilisation qui justifierait la complexité du code et l'effort de maintenance requis.
En résumé, la bonne réponse à la question posée est non, ne fais pas ça .