dans un titre "forçant une colection à ordures" em> du livre "C # 2010 et la plate-forme .NET 4" EM> par Andrew Troelsen écrit: P>
"Encore une fois, tout le but du collecteur de poubelles .NET est de gérer la mémoire en notre nom. Cependant, dans certaines circonstances très rares, il peut être utile de forcer programmatiquement une collection de déchets à l'aide de GC.Collect (). Spécifiquement: p>
• Votre application est sur le point d'entrer dans un bloc de code que vous ne voulez pas interrompre par une collection possible de déchets.
...
" p>
Mais arrêtez! Y a-t-il un tel cas où la collecte des ordures est indésirable? Je n'ai jamais vu / lire quelque chose comme ça (à cause de ma petite expérience de développement bien sûr). Si, alors que votre pratique vous avez fait quelque chose comme ça, veuillez partager. Pour moi, c'est un point très intéressant. P>
Merci! P>
6 Réponses :
Oui, il y a absolument un cas lorsque la collection de déchets est indésirable: lorsqu'un utilisateur attend que quelque chose se passe, et ils doivent attendre plus longtemps car le code ne peut pas procéder avant la fin de la collecte des ordures. P>
C'est le point de Troelsen: si vous avez un point spécifique où vous connaissez un GC n'est pas em> problematiquement et est susceptible de collecter des quantités importantes de poubelles em> peut être une bonne idée de la provoquer puis de l'éviter de déclencher à un moment moins opportun. P>
Vous savez que ce n'est pas problématique, encore plus rare que les scénarios où vous voudrez peut-être ...
@Tontyhopkinson: C'est relativement rare, mais pas inouïe de. Plus précisément, vous savez peut-être bien que c'est moins i> problématique maintenant que ce ne serait bientôt.
Il y a toujours une raison de briser les règles, de ne pas discuter que vous ne devriez jamais faire cela, juste avant de les casser, vous devriez les comprendre afin que vous puissiez les casser efficacement.
Ce serait très rare, mais GC peut être un processus modérément coûteux, donc s'il y a une section particulière sensible à la synchronisation, vous ne voulez pas que cette section interrompue par GC. P>
La recommandation est que vous ne devez pas appeler explicitement D'autres ont détaillé certains, et il n'y a aucun doute plus. La première chose à comprendre cependant, est appeler collecter code> dans votre code. Pouvez-vous trouver des circonstances là où il est utile? P>
collecter code> au mauvais point rendra votre performance pire. Pire encore, pour compter sur cela rend votre code très fragile. Les conditions rares nécessaires pour apporter un appel à
collecter code> bénéfique ou enfin non nuisibles, peuvent être complètement annulées avec une simple modification du code, ce qui donnera une oomisation inattendue, une paresseuse performamagnce etc. p>
i Exécution d'un site Web relié à la recette et je stocke un graphique massif de recettes et de leur utilisation de l'ingrédient en mémoire. En raison de la manière dont j'ai pivoter ces informations pour un accès rapide, je dois charger plusieurs concerts de données en mémoire lorsque l'application se charge avant de pouvoir organiser les données dans un graphique très optimisé. Je crée une énorme quantité d'objets minuscules sur le tas que, une fois le graphique construit, deviennent inaccessibles. P>
Tout cela est terminé lorsque l'application Web se charge et prend probablement 4-5 secondes à faire. Après que je le fais, j'appelle Autre que cela, dans mes 12 années de programmation .NET, je n'ai jamais rencontré une situation où je voulais forcer le collecteur des ordures à courir. P> gc.collect (); code> parce que je préférerais réexaminer toute cette mémoire maintenant plutôt que potentiellement bloquez toutes les threads lors d'une requête HTTP entrante pendant que le collecteur des ordures panne nettoyer tous ces objets de courte durée. Je trouve aussi qu'il est préférable de nettoyer maintenant depuis que le tas est probablement moins fragmenté à ce moment-là, puisque mon application n'a pas vraiment fait autre chose d'autre. Retarder cela pourrait entraîner de nombreux autres objets créés et que le tas doit être compressé davantage lorsque GC fonctionne automatiquement. P>
Je l'appelle avant les mesures de la performance afin que le GC ne falsifie pas les résultats.
Une autre situation est une autre situation des tests d'unité des fuites de mémoire: p>
object doesItLeak = /*...*/; //The object you want to have tested WeakReference reference = new WeakRefrence(doesItLeak); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); Assert.That(!reference.IsAlive);
Votre application est sur le point d'entrer dans un bloc de code que vous ne le faites pas vouloir interrompu par une collection d'ordures éventuelles. ... p> blockQuote>
Un argument très suspect (qui est néanmoins utilisé beaucoup). p>
Windows n'est pas un système d'exploitation en temps réel. Votre code (thread / processus) peut toujours être préempté par le planificateur d'exploitation. Vous n'avez pas d'accès garanti à la CPU. P>
Donc, il se résume à: comment le temps d'une gomme GC se compare-t-il à un emplacement temporel (~ 20 ms)? p>
Il y a très peu de données difficiles disponibles à ce sujet, j'ai cherché quelques fois. p>
de ma propre observation (très informelle), une collection GEN-0 est de moins de 40 ms, généralement beaucoup moins. Un GEN-2 complet peut fonctionner dans environ 100 ms, probablement plus. p>
Le «risque» d'être interrompu par le GC est du même ordre de grandeur que d'être échangé pour un autre processus. Et vous ne pouvez pas contrôler ce dernier. p>
Veuillez prendre une note particulière de "certaines circonstances très rares" i> et ne spraspérez pas gc.collect () sur votre code.