C# grand tableau d'octets et de fuite de mémoire si pas entaché de nullité rapidement
J'ai une classe qui a un tableau d'octets holding à partir de 1 048 576 octets jusqu'à 134,217,728 octets.
Dans la dispose vide, j'ai le tableau de valeur null et la méthode de l'appel de la débarrasser des appels GC.Collect
après.
Si je me débarrasser tout de suite que je vais obtenir mon mémoire, mais si j'attends comme 10 heures et d'en disposer, l'utilisation de la mémoire ne change pas.
So far So good. Et quelle est votre question?
je ne comprends pas pourquoi le temps serait la cause de la mémoire pour ne pas être libéré. et si il y a une solution à ce problème.
Lorsque la mémoire est utilisée que long, il sera promu à travers les générations de la collecte des ordures. Quand il est dans les générations suivantes, il a tendance à ne pas obtenir recueillies jusqu'à ce que le système en a besoin, ce n'est pas une fuite de soi. Avez-vous essayé le
p.s. Je n'ai pas vraiment recommandons de forcer le GC, laissez-le GC le faire. Vous êtes maintenant sur la mémoire pendant une longue période, de sorte que le GC suppose que vous allez continuer à le faire et vérifie qu'il est beaucoup moins fréquemment. Rechercher des générations de collecte des ordures pour plus de détails.
Vous n'avez pas expliqué pourquoi c'est un problème. La mémoire n'est pas libérée immédiatement. OK, alors qui s'en soucie? Il sera libéré quand il a besoin d'être libérée. Laissez le garbage collector de faire son travail.
je ne comprends pas pourquoi le temps serait la cause de la mémoire pour ne pas être libéré. et si il y a une solution à ce problème.
Lorsque la mémoire est utilisée que long, il sera promu à travers les générations de la collecte des ordures. Quand il est dans les générations suivantes, il a tendance à ne pas obtenir recueillies jusqu'à ce que le système en a besoin, ce n'est pas une fuite de soi. Avez-vous essayé le
Force
option sur GC.Collect
et spécifier les générations à recueillir?p.s. Je n'ai pas vraiment recommandons de forcer le GC, laissez-le GC le faire. Vous êtes maintenant sur la mémoire pendant une longue période, de sorte que le GC suppose que vous allez continuer à le faire et vérifie qu'il est beaucoup moins fréquemment. Rechercher des générations de collecte des ordures pour plus de détails.
Vous n'avez pas expliqué pourquoi c'est un problème. La mémoire n'est pas libérée immédiatement. OK, alors qui s'en soucie? Il sera libéré quand il a besoin d'être libérée. Laissez le garbage collector de faire son travail.
OriginalL'auteur jasonbay13 | 2011-11-28
Vous devez vous connecter pour publier un commentaire.
L'utilisation de la mémoire est basé sur un système d'allocation de mémoire. Il peut être libéré immédiatement, il peut ne pas l'être. Cela dépend de l'OS de l'utilisation, de l'application, etc. Vous gratuit dans l'exécution, mais cela ne signifie pas que le système d'exploitation toujours qu'il revient. Je pense heres une détermination basée sur la mémoire des modèles (c'est à dire le temps ici) qui affecte ce calcul de quand de le retourner ou pas. Cela a été abordé ici:
Explicitement la libération de la mémoire en c#
OriginalL'auteur Adam Tuliper - MSFT
Remarque: si la mémoire n'est pas libérée, il n'est pas automatiquement moyens qu'il a utilisés. C'est à la CLR si c'est des communiqués de formes de packets de mémoire ou pas, mais cette mémoire n'est pas perdu.
Cela dit, si vous voulez une explication technique, vous aurez envie de lire la littérature sur le Tas d'Objets Volumineux: http://msdn.microsoft.com/en-us/magazine/cc534993.aspx
Fondamentalement, c'est une zone de la mémoire où les objets de très grande taille (plus de 85kB) sont alloués. Il se diffère des autres zones de mémoire qu'il n'est jamais compacté, et donc peuvent être fragmentés. Je pense que ce qui se passe dans votre cas est:
Cas 1: vous allouer l'objet et appeler immédiatement le GC.Collecter. L'objet est attribué à la fin du segment, puis libéré. Le CLR voit gratuitement un segment à la fin de la tas et la restitue à l'OS.
Cas 2: vous allouer l'objet et attendre pendant un certain temps. Dans le même temps, un autre objet est alloué dans la liturgie des heures. Maintenant, votre objet n'est pas le dernier plus. Ensuite, lorsque vous appelez GC.Collecter, votre objet est effacé, mais il y a encore de l'autre objet(s) à la fin du segment de mémoire. Ainsi, le CLR ne peut pas libérer la mémoire pour le système d'exploitation.
Juste une supposition basée sur ma connaissance de la gestion de la mémoire .NET. Je suis peut-être complètement faux.
OriginalL'auteur Kevin Gosse
Vos résultats ne sont pas exceptionnels, mais cela ne signifie pas que tout est mauvais. Afin d'être collectées, quelque chose doit invite le gouvernement pour recueillir (souvent une tentative de répartition). Comme un résultat, vous pouvez construire une application qui consomme un paquet de mémoire, la libère, et puis s'en va au ralenti. Si il n'y a pas de pression de mémoire sur la machine, et si votre application ne pas essayer de faire quelque chose après cela, le GC ne se déclenche pas (car il n'en a pas besoin). Une fois que vous êtes occupé, le GC coup de pied dans et faire son travail. Ce comportement est très souvent pris pour une fuite.
BTW:
Utilisez-vous qu'un très grand éventail plus d'une fois? Si oui, vous pourriez être mieux de le garder autour de et de le réutiliser. La raison: tout objet de plus de 85 000 octets est alloué sur le Tas d'Objets Volumineux. Ce segment ne reçoit GC avais sur les collections de Génération 2. Donc, si vous êtes affectation et la réaffectation des tableaux très souvent, vous allez être la cause de beaucoup de Gen 2 (cher) des collections.
(note: cela ne veut pas dire qu'il y a une règle dure et rapide pour toujours la réutilisation de grands tableaux, mais si vous faites beaucoup de l'allocation/désallocation/allocation d'un tableau, vous devez mesurer combien il aide si vous ré-utiliser).
Je vois. Si vous voulez vraiment tester si une fuite se produit, vous pouvez jeter un peu de code de test qui ne cesse de créer et de sortir ces tableaux indéfiniment. Ils finiront par s'en aller. Probablement ce qui se passe c'est qu'il n'y a pas assez de pression sur le système pour demander une collection de Génération 2. Ou, il pourrait être comme Adam Tuliper dit -- le tableau est libéré, mais la mémoire n'est pas de revenir à l'O/S immédiatement. De toute façon, tant que vous n'êtes pas tenue d'une référence à la matrice quelque part, il n'est probablement pas une véritable fuite.
OriginalL'auteur JMarsch