Quelle est la bonne façon de gérer le manque de mémoire dans la mémoire?

StackOverflow https://stackoverflow.com/questions/1439977

  •  10-07-2019
  •  | 
  •  

Question

Récemment, je travaille sur un programme de lecteur vidéo sous Windows pour un programme de vidéosurveillance. Étant donné que le programme doit décoder et lire plusieurs flux vidéo en même temps, je pense qu'il pourrait rencontrer le problème d'échec de malloc et j'ajoute une vérification après chaque malloc.

Mais à vrai dire, dans ce code de programmes open source que j'ai lu dans des projets open source, je trouve rarement une vérification du résultat de malloc. Ainsi, lorsque malloc échoue, la plupart des programmes ne fonctionnent plus. N'est-ce pas inacceptable?

Mes collègues qui écrivent des programmes serveur sous Linux alloueront suffisamment de mémoire pour 100 connexions client. Ainsi, bien que son programme puisse refuser le client 101, il ne rencontrera jamais un échec de malloc. Son approche convient-elle également aux applications de bureau?

Était-ce utile?

La solution

Sous Linux, malloc () n'échouera jamais. Au lieu de cela, le tueur de MOO sera déclenché et commencera à tuer les processus aléatoires jusqu'à ce que le système bascule. Étant donné que Linux est le dérivé UNIX le plus répandu et utilisé aujourd'hui, de nombreux développeurs ont appris à ne jamais vérifier le résultat de malloc () . C'est probablement pour cette raison que vos collègues ignorent les échecs malloc () .

Sur les systèmes d'exploitation prenant en charge les échecs, j'ai observé deux modèles généraux:

  • Écrivez une procédure personnalisée qui vérifie le résultat de malloc () et appelle abort () en cas d'échec de l'allocation. Par exemple, les bibliothèques GLib et GTK + utilisent cette approche.

  • Stocker une liste globale de "purge-capable" les allocations, telles que les caches, qui peuvent être effacées en cas d'échec de l'allocation. Ensuite, essayez à nouveau l’allocation et, si elle échoue toujours, signalez-la via les mécanismes standard de signalement des erreurs (qui ne procèdent pas à une allocation dynamique).

Autres conseils

Suivez l'API normalisée

Même sous Linux, ulimit peut être utilisé pour obtenir un retour d'erreur Malloc rapide. La valeur par défaut est illimitée.

Il existe une pression manifeste pour se conformer aux normes publiées. Sur la plupart des systèmes, à long terme et même éventuellement sous Linux, malloc (3) renverra une indication correcte d'échec. Il est vrai que les systèmes de bureau ont de la mémoire virtuelle et une pagination à la demande, mais même en ne vérifiant pas malloc ( 3) ne fonctionne que dans un programme débogué sans fuite de mémoire. En cas de problème, quelqu'un voudra définir un ulimit . et le traquer. Soudain, la vérification malloc prend tout son sens.

Utiliser le résultat de malloc sans rechercher la valeur null est inacceptable dans le code pouvant être utilisé sur les plates-formes où malloc peut échouer. Sur ceux-là, cela aura tendance à provoquer des plantages et un comportement imprévisible. Je ne peux pas prédire l'avenir, je ne sais pas où va mon code, alors j'écrirais du code avec des chèques pour que malloc renvoie null - mieux vaut mourir que de se comporter de façon imprévisible!

Les stratégies à suivre en cas d’échec de malloc dépendent du type d’application et du degré de confiance que vous accordez aux bibliothèques que vous utilisez. Dans certaines situations, la seule chose à faire est d’arrêter le programme dans son intégralité.

L'idée de préallouer un quota de mémoire connu et de la répartir en plusieurs morceaux, évitant ainsi l'épuisement de la mémoire, est une bonne idée, si l'utilisation de la mémoire par votre application est prédictible. Vous pouvez étendre cela à l'écriture de vos propres routines de gestion de la mémoire à utiliser avec votre code.

Cela dépend du type d'application sur laquelle vous travaillez. Si l'application effectue un travail divisé en tâches discrètes dans lesquelles une tâche individuelle peut échouer, la vérification de l'allocation de mémoire peut être récupérée de manière transparente.

Mais dans de nombreux cas, le seul moyen raisonnable de réagir à une défaillance de malloc consiste à terminer le programme. Permettre à votre code de planter sur l’inévitable déréférence null permettra d’atteindre cet objectif. Il serait certainement toujours préférable de vider une entrée de journal ou un message d'erreur expliquant l'erreur, mais dans le monde réel, nous travaillons sur des calendriers limités. Parfois, le retour sur investissement de la gestion des erreurs pédantes n’est pas possible.

Toujours vérifier et préallouer un tampon qui peut être libéré dans ce cas afin que vous puissiez avertir l'utilisateur de sauvegarder ses données et de fermer l'application.

Dépend de l'application que vous écrivez. Bien sûr, vous devez toujours vérifier la valeur de retour de malloc (). Cependant, gérer correctement le MOO n'a de sens que dans des cas très précis, tels que des services système cruciaux de bas niveau, ou lors de l'écriture d'une bibliothèque qui pourrait être utilisée par eux. Avoir un wrapper malloc qui abandonne le MOO est donc très courant dans de nombreuses applications et frameworks. Ces wrappers sont souvent nommés xmalloc () ou similaire.

La fonction g_malloc () de GLib est également abandonnée.

Si vous allez gérer d’énormes quantités de mémoire et que vous souhaitez faire des déclarations sous Linux, comme suit: "maintenant, j’ai la mémoire ABC et je n’ai pas besoin de la partie B, faites comme vous le souhaitez", jetez un oeil à mmap () / madvise () famille de fonctions disponibles en stock bibliothèque GNU C. En fonction de vos habitudes d'utilisation, le code peut s'avérer encore plus simple que d'utiliser malloc. Cette API peut également être utilisée pour aider Linux à ne pas gaspiller de la mémoire en mettant en cache les fichiers que vous allez lire / écrire une seule fois.

Ils sont bien documentés dans la documentation de GNU libc info.

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