6
votes

Collection de déchets indésirables

dans un titre "forçant une colection à ordures" du livre "C # 2010 et la plate-forme .NET 4" par Andrew Troelsen écrit:

"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:

• 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. ... "

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.

Merci!


1 commentaires

Veuillez prendre une note particulière de "certaines circonstances très rares" et ne spraspérez pas gc.collect () sur votre code.


6 Réponses :


7
votes

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.

C'est le point de Troelsen: si vous avez un point spécifique où vous connaissez un GC n'est pas problematiquement et est susceptible de collecter des quantités importantes de poubelles peut être une bonne idée de la provoquer puis de l'éviter de déclencher à un moment moins opportun.


3 commentaires

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 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.



1
votes

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.


0 commentaires

3
votes

La recommandation est que vous ne devez pas appeler explicitement collecter dans votre code. Pouvez-vous trouver des circonstances là où il est utile?

D'autres ont détaillé certains, et il n'y a aucun doute plus. La première chose à comprendre cependant, est ne le fais pas . C'est un dernier recours, étudie d'autres options, apprendre comment les travaux de GC examinent la manière dont votre code est affecté, suivez les meilleures pratiques pour vos conceptions.

appeler collecter 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 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.


0 commentaires

5
votes

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.

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 gc.collect (); 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.

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.


0 commentaires

2
votes

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);


0 commentaires

1
votes

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. ...

Un argument très suspect (qui est néanmoins utilisé beaucoup).

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.

Donc, il se résume à: comment le temps d'une gomme GC se compare-t-il à un emplacement temporel (~ 20 ms)?

Il y a très peu de données difficiles disponibles à ce sujet, j'ai cherché quelques fois.

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.

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.


0 commentaires