C'est possible.
Il existe deux conditions différentes de manque de mémoire que vous pouvez rencontrer sous Linux. Ce que vous rencontrez dépend de la valeur de sysctl vm.overcommit_memory
(/proc/sys/vm/overcommit_memory
)
Introduction:
Le noyau peut effectuer ce qu'on appelle un "overcommit de mémoire". C'est à ce moment que le noyau alloue aux programmes plus de mémoire qu'il n'y en a réellement dans le système. Ceci est fait dans l'espoir que les programmes n'utiliseront pas réellement toute la mémoire qu'ils ont allouée, car c'est un phénomène assez courant.
overcommit_memory =2
Quand overcommit_memory
est défini sur 2
, le noyau n'effectue aucun overcommit. Au lieu de cela, lorsqu'un programme se voit allouer de la mémoire, il est garanti d'avoir accès à cette mémoire. Si le système ne dispose pas de suffisamment de mémoire libre pour satisfaire une demande d'allocation, le noyau renverra simplement un échec pour la demande. C'est au programme de gérer la situation avec élégance. Si elle ne vérifie pas que l'allocation a réussi alors qu'elle a réellement échoué, l'application rencontrera souvent une erreur de segmentation.
Dans le cas de l'erreur de segmentation, vous devriez trouver une ligne comme celle-ci dans la sortie de dmesg
:
[1962.987529] myapp[3303]: segfault at 0 ip 00400559 sp 5bc7b1b0 error 6 in myapp[400000+1000]
Le at 0
signifie que l'application a tenté d'accéder à un pointeur non initialisé, ce qui peut être le résultat d'un appel d'allocation de mémoire qui a échoué (mais ce n'est pas le seul moyen).
overcommit_memory =0 et 1
Quand overcommit_memory
est défini sur 0
ou 1
, la surcharge est activée et les programmes sont autorisés à allouer plus de mémoire que ce qui est réellement disponible.
Cependant, lorsqu'un programme veut utiliser la mémoire qui lui a été allouée, mais que le noyau constate qu'il n'a pas assez de mémoire pour le satisfaire, il doit récupérer de la mémoire. Il essaie d'abord d'effectuer diverses tâches de nettoyage de la mémoire, telles que comme vidage des caches, mais si cela ne suffit pas, il mettra alors fin à un processus. Cette terminaison est effectuée par l'OOM-Killer. L'OOM-Killer examine le système pour voir quels programmes utilisent quelle mémoire, depuis combien de temps ils s'exécutent, qui les exécute et un certain nombre d'autres facteurs pour déterminer lequel est tué.
Une fois le processus arrêté, la mémoire qu'il utilisait est libérée et le programme qui vient de provoquer la condition de mémoire insuffisante dispose désormais de la mémoire dont il a besoin.
Cependant, même dans ce mode, les programmes peuvent toujours se voir refuser les demandes d'allocation.Lorsque overcommit_memory
est 0
, le noyau essaie de deviner au mieux quand il doit commencer à refuser les demandes d'allocation. Lorsqu'il est défini sur 1
, je ne suis pas sûr de la détermination qu'il utilise pour déterminer quand il doit refuser une demande, mais il peut refuser des demandes très volumineuses.
Vous pouvez voir si OOM-Killer est impliqué en regardant la sortie de dmesg
, et trouver un message tel que :
[11686.043641] Out of memory: Kill process 2603 (flasherav) score 761 or sacrifice child
[11686.043647] Killed process 2603 (flasherav) total-vm:1498536kB, anon-rss:721784kB, file-rss:4228kB
La vérité est que, quelle que soit la façon dont vous le regardez - que votre processus soit bloqué à cause du gestionnaire de mémoire du système ou à cause de quelque chose d'autre - il est toujours un bug. Qu'est-il arrivé à toutes ces données que vous étiez en train de traiter en mémoire ? Il aurait dû être enregistré.
Alors que overcommit_memory=
est la manière la plus générale de configurer la gestion du MOO Linux, elle est également ajustable par processus comme :
echo [-+][n] >/proc/$pid/oom_adj
Utilisation de -17
dans ce qui précède exclura un processus de la gestion du manque de mémoire. Ce n'est probablement pas une bonne idée en général, mais si vous êtes à la recherche de bogues, cela pourrait en valoir la peine - surtout si vous souhaitez savoir si c'était OOM ou votre code. L'incrémentation positive du nombre rendra le processus plus susceptible d'être tué dans un événement OOM, ce qui pourrait vous permettre de mieux renforcer la résilience de votre code dans les situations de mémoire insuffisante et de vous assurer que vous quittez gracieusement si nécessaire.
Vous pouvez vérifier les paramètres actuels du gestionnaire de MOO par processus comme :
cat /proc/$pid/oom_score
Sinon, vous pourriez devenir suicidaire :
sysctl vm.panic_on_oom=1
sysctl kernel.panic=X
Cela configurera l'ordinateur pour qu'il redémarre en cas de manque de mémoire. Vous définissez le X
ci-dessus au nombre de secondes pendant lesquelles vous souhaitez que l'ordinateur s'arrête après une panique du noyau avant de redémarrer. Devenir fou.
Et si, pour une raison quelconque, vous décidez que vous l'aimez, rendez-le persistant :
echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf