71 votes

Les implémentations malloc vont-elles restituer de la mémoire libre au système?

J'ai une longue durée de vie de l'application avec de fréquentes allocation de mémoire-libération. Toute la fonction malloc de la mise en œuvre de retour libéré de la mémoire vers le système?

Qu'est-ce que, à cet égard, le comportement de:

  • ptmalloc 1, 2 glibc (par défaut) ou 3
  • dlmalloc
  • tcmalloc (google filetée malloc)
  • solaris 10 et 11 par défaut malloc et mtmalloc
  • FreeBSD 8 par défaut malloc (jemalloc)
  • Hoard malloc?

Mise à jour

Si j'ai une demande dont la consommation de mémoire peuvent être très différentes dans la journée et pendant la nuit (par exemple), peut-on forcer tout de malloc est de retour libéré de la mémoire pour le système?

Sans ce retour de mémoire libérée sera échangé et dans beaucoup de fois, mais cette mémoire ne contient que des ordures.

42voto

Shashi Points 146

L'analyse qui suit s'applique uniquement pour la glibc (basé sur ptmalloc2 algorithme). Il y a certaines options qui vous paraissent utiles pour le retour de la mémoire libérée vers le système:

  1. mallopt() (définie en malloc.h) fournit une option pour définir la garniture de seuil de valeur à l'aide de l'un de l'option de paramètre M_TRIM_THRESHOLD, ce qui indique le montant minimum de libérer de la mémoire (en octets) a permis au sommet du segment de données. Si le montant est inférieur à ce seuil, la glibc invoque brk() de redonner de la mémoire du noyau.

    La valeur par défaut de M_TRIM_THRESHOLD sous Linux est mis à 128K, la définition d'une valeur inférieure peut économiser de l'espace.

    Le même comportement peut être atteint par la création de la garniture de seuil de valeur dans la variable d'environnement MALLOC_TRIM_THRESHOLD_, sans changement de source absolument.

    Toutefois, les premiers programmes de test exécuté à l'aide d' M_TRIM_THRESHOLD a montré que, même si la mémoire allouée par malloc retourne au système, la partie restante de la réelle partie de la mémoire(l'arène) initialement demandée par brk() a tendance à être conservé.

  2. Il est possible de découper la mémoire de l'arène et de donner de la mémoire inutilisée vers le système en appelant malloc_trim(pad) (définie en malloc.h). Cette fonction permet de redimensionner le segment de données, en laissant au moins pad octets à la fin de celui-ci et de l'échec, si moins d'une page vaut la peine d'octets peut être libéré. De la taille de Segment est toujours un multiple d'une seule page, qui est de 4 096 octets sur i386.

    La mise en œuvre de cette modification du comportement de l' free() l'aide malloc_trim pourrait être fait à l'aide de la fonction malloc crochet de la fonctionnalité. Cela ne nécessiterait aucune modification du code source du noyau de la bibliothèque glibc.

  3. à l'aide de madvise() système d'appel à l'intérieur de la gratuit de la mise en œuvre de la glibc.

19voto

Alex Martelli Points 330805

La plupart des implémentations ne vous embêtez pas à l'identification de ceux (assez rares) cas où l'intégralité de "blocs" (quelque soit la taille convient à l'OS) ont été libérés et pourrait être retournés, mais il y a bien sûr des exceptions. Pour exemple, je cite la page de wikipedia, dans OpenBSD:

Sur un appel à l' free, la mémoire est libérée et non mappés à partir du processus d'adresse l'espace à l'aide de munmap. Ce système est conçu pour améliorer la sécurité l'avantage du format d'espace d'adresse la randomisation et de l'écart de fonctions de la page mis en œuvre dans le cadre d'OpenBSD mmap appel système et détecter les use-after-free bugs-comme une grande mémoire l'allocation est complètement déchargés de la mémoire après il est libéré, la poursuite de l'utilisation des causes une erreur de segmentation et de résiliation de le programme.

La plupart des systèmes ne sont pas aussi centré sur la sécurité que OpenBSD, cependant.

Sachant cela, quand je suis le codage d'un long-système en cours d'exécution qui a connu-à-être transitoire une exigence pour une grande quantité de mémoire, j'essaie toujours d' fork le processus: le parent alors juste attend les résultats de l'enfant [[généralement sur un tuyau]], l'enfant fait le calcul (y compris l'allocation de mémoire), renvoie les résultats [[on dit pipe]], puis se termine. De cette manière, mon long processus en cours d'exécution ne sera pas inutilement accaparer la mémoire pendant le long temps entre occasionnels "pointes" dans sa demande de mémoire. D'autres stratégies alternatives incluent le passage à une coutume allocateur de mémoire pour des exigences spéciales (C++ en fait assez facile, bien que les langues avec virtual machines à sous telles que Java et Python n'est généralement pas).

6voto

Laurent Debricon Points 886

Je fais affaire avec le même problème que l'OP. Jusqu'à présent, il semble possible avec tcmalloc. J'ai trouvé deux solutions:

  1. compiler votre programme avec tcmalloc lié, puis de le lancer en tant que :

    env TCMALLOC_RELEASE=100 ./my_pthread_soft
    

    la documentation mentionne que

    Des tarifs raisonnables sont dans l'intervalle [0,10].

    mais 10 ne semble pas suffisant pour moi (j'.e je ne vois pas de changement).

  2. trouver quelque part dans votre code où il serait intéressant de libérer toute la mémoire libérée, puis ajoutez ce code:

    #include "google/malloc_extension_c.h" // C include
    #include "google/malloc_extension.h"   // C++ include
    
    /* ... */
    
    MallocExtension_ReleaseFreeMemory();
    

La deuxième solution a été très efficace dans mon cas; le premier serait grand, mais il n'est pas très réussie, il est compliqué de trouver le bon numéro, par exemple.

4voto

Andrew McGregor Points 7641

Parmi ceux que vous avez répertoriés, seul Hoard restituera de la mémoire au système ... mais s'il le peut, cela dépendra beaucoup du comportement de votre programme en matière d'allocation.

3voto

dkantowitz Points 1178

Pour tous les mallocs «normaux», y compris ceux que vous avez mentionnés, la mémoire est libérée pour être réutilisée par votre processus, mais pas pour l'ensemble du système. La remise à l'ensemble du système ne se produit que lorsque votre processus est finalement terminé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X