10 votes

Appels GC.collect() problématiques dans les bibliothèques tierces

En profilant mon application (C#, .NET 4), j'ai remarqué qu'une bibliothèque tierce que j'utilise appelle explicitement GC.Collect(). C'est très ennuyeux car cela a parfois un impact dramatique sur les performances de mon application, car certains appels à cette bibliothèque se terminent par des boucles énormes : le temps passé dans GC.Collect représente plus de 80% du temps d'exécution total.

Bien sûr, j'ai signalé ce comportement aux responsables de la bibliothèque (la librairie n'est pas open-source), mais pendant qu'ils travaillent sur une nouvelle version, j'aimerais optimiser mon application. Que puis-je faire ?

J'ai essayé de configurer la GC en définissant GCSettings.LatencyMode sur GCLatencyMode.LowLatency (uniquement pendant l'exécution des appels à la bibliothèque, bien sûr), mais en vain. Je préfère éviter de forker mon processus.

Des idées ?

7voto

Bobby Points 6894

Il y a deux chemins que vous pouvez prendre, le premier est Parcheando vous-même, le second est d'informer le développeur de la bibliothèque à ce sujet (déposer un rapport de bug).

Parcheando vous-même est assez facile, obtenez Réflecteur RedGates avec le Reflexil AddIn et rafistoler la bibliothèque. Vous pouvez également obtenir le Éditeur IL DotNet qui fait fondamentalement la même chose, mais qui est FLOSS.

Le problème de l'approche "patch it yourself" est qu'elle présente des inconvénients :

  • Les futures versions des bibliothèques devront également être corrigées. Il est donc préférable de conserver des traces de ce que vous avez fait.
  • Vous ne comprenez pas les internes de la bibliothèque, s'il y a 10 appels à GC.Collect() et qu'un seul d'entre eux est légitime (j'en doute, mais c'est possible), vous casserez la bibliothèque en les supprimant tous.
  • Vous violerez très probablement la licence de la bibliothèque, ce qui peut vous envoyer dans l'enfer juridique. Mais cela dépend de la façon dont vous utilisez la bibliothèque, dans quel logiciel et comment le paquet final est distribué.

L'autre chose que vous pouvez faire est de signaler un bogue aux développeurs originaux de la bibliothèque. Veillez à ne pas faire preuve de suffisance à ce sujet et fournissez plutôt des ressources utiles, comme l'article MSDN sur le GC et une application de test avec les résultats du profileur qui montre le problème.

3voto

supercat Points 25534

Avant d'essayer de modifier les choses pour empêcher le code d'effectuer une GC, il peut être utile de se demander pourquoi il le fait. Alors qu'un code bien écrit devrait simplement laisser le GC être invoqué lorsque .Net pense que c'est nécessaire, il est certainement possible d'écrire du code qui exige que le GC soit exécuté à certains moments pour garantir la correction. Je peux imaginer trois raisons pour lesquelles le code pourrait appeler le GC :

  1. Les appels GC ont été ajoutés à des fins de profilage de la mémoire, et laissés par inadvertance/inappropriés.
  2. Le développeur a pensé que c'était une bonne idée, même si cela n'apporte aucun avantage réel.
  3. Un certain type de ressource gérée a été abandonné par erreur ; le fait de forcer un GC peut permettre à cette ressource abandonnée d'être nettoyée suffisamment tôt pour permettre une exécution correcte (bien que lente) du programme.

Si le GC forcé existe en raison du scénario 3, sa suppression peut entraîner de mauvaises choses.

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