Articles
Types de collecte des ordures dans .Net Core
2 septembre 2019 • 5 min de lecture
La gestion de la mémoire dans les langages modernes est souvent une arrière-pensée. Pour tous les intents et purposes, nous écrivons des logiciels sans la moindre pensée à la mémoire. Cela nous sert bien, mais il y a toujours des exceptions…
En Californie, il existe des exigences de rapports financiers étendues pour les agences d’éducation locale (LEA). Une LEA peut être un comté, un district, une charte ou une école unique. La plupart des LEA créent leurs propres rapports financiers qui sont généralement centrés sur Excel. Il n’est pas surprenant que chaque rapport soit différent. Pour résoudre ce problème, le California Board of Education a commandé un logiciel pour générer des rapports financiers.
J’ai fait partie de l’équipe de développement.
Ma première étape a été les journaux de test. Les journaux d’Ed-Pro pointaient vers une utilisation élevée de la mémoire. Y avait-il une fuite mémoire ? Un ingénieur a observé que les calculs d’Ed-Pro utilisaient une grande quantité de mémoire de courte durée. Si la mémoire n’était pas nettoyée rapidement, cela pouvait ressembler à une fuite mémoire.
Ed-Pro est construit sur .Net Core, le framework multi-plateforme de Microsoft. Dans .Net Core, la mémoire est divisée en trois tags : courte durée (Gen0), durée moyenne (Gen1) et longue durée (Gen2). Gen0 est pour les données de courte durée qui sortent rapidement de la portée, Gen1 est pour la mémoire de durée moyenne qui persiste un peu plus longtemps, elle sort également finalement de la portée et Gen2 est la mémoire de longue durée qui peut vivre pendant toute la durée de vie de l’application. La mémoire Gen0 est constamment récupérée, Gen1 est récupérée moins fréquemment que Gen0, et Gen2 est récupérée encore moins fréquemment que Gen1.
Le seul moyen sûr de comprendre l’utilisation de la mémoire d’Ed-Pro était de la profiler. Ci-dessous se trouve une capture d’écran utilisant dotMemory de JetBrains.
Comme prévu, nous avons trouvé de grandes quantités de mémoire Gen0 (le bleu), tellement que la collecte des ordures ne pouvait pas suivre. Une stratégie pour compenser une grande quantité de mémoire a causé une oscillation de la collecte des ordures entre l’augmentation de l’espace mémoire (ajout de plus de mémoire pour l’utilisation de l’application) et son nettoyage. Pendant les cycles de nettoyage, l’application ne répond pas.
Au début, nous étions perplexes. N’est-ce pas le but du GC de garder la mémoire propre ? Deux articles ont été essentiels pour notre compréhension du fonctionnement de la collecte des ordures dans .Net : l’article de Mark Vincze Troubleshooting high memory usage with ASP.Net Core on Kubernetes et Fundamentals of Garbage Collection par Microsoft. Les deux sont d’excellentes lectures et ont apporté de la clarté à l’utilisation de la mémoire dans Ed-Pro.
Voici un résumé de ce que nous avons appris. Il existe deux types de collecte des ordures dans .Net : la collecte des ordures serveur et la collecte des ordures station de travail.
La collecte des ordures serveur fait un couple d’hypothèses : premièrement, il y a beaucoup de mémoire disponible et deuxièmement, les processeurs sont multi-cœurs et rapides. Les deux peuvent être vrais, mais nous vivons dans un monde de machines virtuelles et Docker où il est plus probable que les deux hypothèses soient fausses.
La collecte des ordures serveur permet à la mémoire de s’accumuler. À un moment donné, elle fait l’une de deux choses : soit elle augmente l’espace mémoire permettant à la mémoire de croître, soit elle libère la mémoire orpheline. Lorsqu’elle choisit de libérer de la mémoire, la collecte des ordures démarre le processus sur un thread de haute priorité. Le thread de haute priorité a une priorité plus élevée que l’application. Si la machine est rapide, le nettoyage ne devrait pas être remarqué. Cependant, si ce n’est pas le cas, cela causera l’arrêt de l’application jusqu’à ce que le nettoyage soit terminé.
La collecte des ordures station de travail fonctionne différemment. Elle s’exécute continuellement en récupérant la mémoire sur un thread avec la même priorité que l’application. Cela signifie qu’elle est également en concurrence pour les ressources avec l’application, ce qui peut causer une lenteur de l’application. L’avantage est que l’utilisation de la mémoire de l’application peut rester assez faible, principalement lorsqu’elle utilise de grandes quantités de Gen0.
Par défaut, si .Net Core détecte un serveur, il exécute le type de collecte des ordures serveur, ce qui était le cas avec notre application. Pour exécuter le type de collecte des ordures station de travail, ajoutez l’extrait suivant à votre fichier projet :
<PropertyGroup>
<ServerGarbageCollection>false</ServerGarbageCollection>
</PropertyGroup>
Nous avons apporté cette modification de configuration à Ed-Pro. En utilisant dotMemory, nous avons profilé la mémoire d’Ed-Pro avec la collecte des ordures station de travail activée et chargé les mêmes écrans que dans le test précédent. Voici les résultats :
L’utilisation de la mémoire est considérablement réduite. Les allocations Gen0 sont pratiquement inexistantes. Au-delà des différences du graphique, l’utilisation de la mémoire de la collecte des ordures serveur a atteint 1 gig tandis que la collecte des ordures station de travail a atteint environ 200 megs.
Chaque application est différente. Notre application utilisait une tonne de données temporaires et utilise donc une tonne de mémoire Gen0. Votre application peut exploiter une mémoire plus longue comme Gen1 ou Gen2, auquel cas la collecte des ordures serveur a beaucoup de sens. Mon conseil est de profiler votre mémoire dans différentes conditions pour avoir une idée de la façon dont la mémoire est utilisée, puis de décider quel mode est le meilleur pour votre application.
Auteur : Chuck Conway est un ingénieur IA avec près de 30 ans d’expérience en génie logiciel. Il construit des systèmes IA pratiques — pipelines de contenu, agents d’infrastructure et outils qui résolvent des problèmes réels — et partage ce qu’il apprend en chemin. Connectez-vous avec lui sur les réseaux sociaux : X (@chuckconway) ou visitez-le sur YouTube et sur SubStack.