6
votes

Comment éviter une fuite de mémoire lorsque vous appuyez sur Ctrl + C sous Linux?

Dans mon programme écrit avec C et C ++, je vais un nouvel objet pour remplir la tâche, puis supprimer l'objet.

Au moment de la nouvelle autre objet, mais avant la suppression d'objet, si l'utilisateur appuie sur Ctrl + c pour casser le processus, cela entraînera la suppression de ne pas être appelée et un Une fuite de mémoire se produit.

Que dois-je faire pour éviter cette situation?

En outre, si la mémoire a été récupérée par le système d'exploitation, qu'en est-il des fichiers ouverts? Sont-ils fermés par le système d'exploitation ou devrais-je les fermer manuellement?


1 commentaires

Quelqu'un peut-il s'il vous plaît S / Linux / Unix / Pour généraliser ceci?


7 Réponses :


7
votes

Dans un système basé sur la mémoire virtuelle, toute la mémoire est renvoyée au système d'exploitation lorsqu'un processus est résilié, que cela soit libéré explicitement dans le code de l'application. La même chose pourrait ne pas être vraie des autres ressources, cependant, que vous voudrez peut-être libérer proprement. Dans ce cas, vous devez fournir un gestionnaire de signal personnalisé pour le signal Sigint (qui est reçu sur CTRL + C), voir par exemple http://linux.die.net/man/2/sigaction .


2 commentaires

Cela signifie-t-il que je ne devrais pas vous soucier de la mémoire allouée? Mais j'ai trouvé que mon destructeur n'était pas appelé.Aussi que le fichier ouvert a été fermé par OS?


@ PDF1001- Même si le système d'exploitation fait partie du travail pour vous, c'est toujours une bonne idée de nettoyer après vous-même autant que possible. Le système d'exploitation n'appellera pas vos destructeurs, il libérera directement toute la mémoire que votre programme a attribué. Si je me souviens bien, vous êtes seul en ce qui concerne les poignées de fichier. En cas de doute, jouez-vous en sécurité et ne supposez pas que le système d'exploitation en fera d'autre.



1
votes

Le système d'exploitation récupérera la mémoire allouée par le processus lorsque le processus quitte le résultat de Ctrl-C ou de tout autre moyen.


0 commentaires

7
votes

Appuyez sur Ctrl C envoyer un SIGINT au processus, qui par défaut fait une fermeture essentiellement ordonnée, y compris la déchirure de la mémoire. manager et libérant tous les tas et empiler alloués. Si vous devez effectuer d'autres tâches, vous devrez installer un sigint gestionnaire et exécuter ces tâches vous-même.


0 commentaires

2
votes

Lorsque CTRL + C est enfoncé dans une console Linux, le signal SIGINT est envoyé à l'application qui, si le signal n'a pas de gestionnaire, terminera le programme, renvoyant toute la mémoire au système d'exploitation. Bien entendu, cela ferait évidemment de faire une libération de mémoire, car toute mémoire sera libérée une fois que le programme existe. Toutefois, si vous souhaitez gérer le signal Sigint Ctrl + C (peut-être pour écrire quelques dernières données à un fichier ou faire un autre nettoyage), vous pouvez utiliser le signal de fonction () pour installer un fonction à appeler lorsque le signal est reçu. Découvrez la page Homme pour cette fonction si vous souhaitez en savoir plus.


0 commentaires

3
votes

Si vous avez alloué des segments de mémoire partagés SYSV à l'aide de shmget (2) , vous devez nettoyer après vous-même avec shmctl (2) . .

Si vous avez attribué des segments de mémoire partagés POSIX à l'aide de shm_open (3) , vous devez nettoyer après vous-même avec shm_unlink (3) . .

Les segments de mémoire partagés SYSV et POSIX persistent la résiliation du processus passé. Vous pouvez voir ce qui persiste à l'aide de l'outil IPCS (1) .

Bien sûr, si vous n'avez utilisé aucun segments de mémoire partagée SYSV ou POSIX, tout cela est tout simplement le bruit. :)


0 commentaires

2
votes

Si le processus quitte, une fuite de mémoire ne se produira pas normalement.

La plupart de la mémoire que vous allouez sera libérée sur CTRL + C. Si vous voyez une utilisation de la mémoire ne revient pas à son niveau préalable, il est presque certainement causé par des blocs de système de fichiers tamponnés.

Cependant, vous devez absolument nettoyer les choses, en particulier si vous avez utilisé d'autres types de ressources:

  • Les fichiers créés dans des répertoires temporaires ne seront pas supprimés. Cela inclut / dev / shm, laissant un tel fichier pourrait être considéré comme une "fuite de mémoire".
  • Les segments de mémoire partagés System V ou POSIX ne seront pas éloignés lorsque votre processus quitte. Si cela vous dérange, nettoyez-les spécifiquement. Alternativement, nettoyez-les sur une course ultérieure.

    Normalement une fuite (d'un objet persistant ou semi-persistant par exemple) n'a pas d'importance si une exécution ultérieure ne fuit pas plus la mémoire. Donc, le nettoyage sur une future course est assez bon.

    Imaginez un processus en cours d'exécution toutes les 5 minutes de "Cron", s'il s'écrase sur chaque course et laisse du désordre, il est toujours correct fourni chaque exécution nettoie le gâchis de l'accident précédent.


0 commentaires

3
votes

Vous vous abonnez à une idée fausse assez courante que les blocs de tas non libérés, mais toujours accessibles au moment où un programme existe des fuites. Ce n'est pas vrai. Les blocs de fuite sont ceux qui aucun pointeur ne se réfère toujours, par conséquent, ils ne peuvent pas être libérés.

À travers les années de jouer avec (et de briser) de nombreux noyaux parfaitement bons, je n'ai jamais réussi à casser suffisamment un gestionnaire de mémoire virtuel au point où il ne récupère plus l'espace d'adressage complet d'un processus une fois qu'il sortit. À moins que vous travailliez avec un noyau clairement marqué comme «nouveau et expérimental», vous aurez une chance de gagner la chance de gagner la loterie que de trouver un système qui n'obtient pas de gestionnaire de mémoire virtuel efficace.

Ne mettez pas de cruft dans votre code juste pour obtenir un score parfait dans Valgrind. Si vous n'avez aucune tâche de nettoyage réel pour faire d'autres que de libérer la mémoire que a toujours des références valides , vous n'avez pas besoin de déranger. Si une personne jette un Kill -9 à votre programme, vous ne pourrez pas le gérer et verra répéter l'ancien comportement.

Si vous avez des descripteurs de fichier pour nettoyer, les serrures partagées pour abandonner, les flux de flush ou quoi que ce soit d'autre doit se produire, d'autres processus ne vous manquent pas lorsque vous êtes parti, par tous les moyens prennent soin de cela. Il suffit de ne pas ajouter de code qui ne fait rien pour résoudre un non-problème, il semble juste idiot de le faire.

note

Cela allait être à l'origine un commentaire, mais est beaucoup trop long et fronça les sourcils à écrire un nouveau commentaire à la fois.


0 commentaires