Performances du ramasse-miettes C # et .Net

J’essaie de créer un jeu en C # et .NET et je prévoyais de mettre en œuvre des messages qui mettent à jour les objects du jeu dans le monde du jeu. Ces messages seraient des objects de référence C #.

Je souhaite cette approche car il serait plus facile de les envoyer via un réseau si je souhaite que le jeu soit multijoueur.

Mais si j’ai beaucoup de messages, cela ne sera-t-il pas assez stressant pour le ramasse-miettes? Et cela n’affectera-t-il pas le gameplay? Les classes de message elles-mêmes sont assez petites avec 4 ou 5 membres au plus.

Ces messages seront générés quelques fois par seconde pour chaque object du monde du jeu.

Le GC dans les versions ultérieures, mais plus précisément dans la version 4.5, fonctionne de manière asynchrone pour les générations 0 et 1. Cela a fortement réduit l’impact du GC.

Si vos objects ont une durée de vie brève, ils ne doivent généralement pas passer du niveau de génération 0. Le niveau 0 est la génération la plus rapide à nettoyer par le GC.

En fin de compte, je n’envisagerais pas d’optimiser prématurément mon code par crainte des performances du GC.

L’optimisation prématurée est la racine de tous les maux de Donald Knuth

Personnellement, je recommanderais cet article pour une compréhension plus profonde

Dans .NET, le ramasse-miettes a 3 générations, la génération 0, la génération 1 et la génération 2. Chaque fois que le CPG ne collectera pas un object d’une génération, cet object sera promu à la génération suivante.

Vous pourriez potentiellement rencontrer des problèmes si vos objects ont une taille supérieure à 85 Ko. Ces objects seront automatiquement stockés dans le tas d’objects volumineux. Le tas d’objects volumineux sera automatiquement collecté dans les situations suivantes:

  • Les allocations dépassent le seuil des grands objects.
  • Le système est dans une situation de mémoire insuffisante.
  • System.GC.Collect est appelé à la génération 2.

Le problème est que, lorsque le segment d’object volumineux est collecté, la mémoire des objects est désallouée mais la mémoire LOH n’est pas compactée. Étant donné que LOH est fragmenté, vous pouvez éventuellement obtenir des exceptions SystemOutOfMemory s’il n’y a pas suffisamment d’espace pour votre object sur LOH.

Des techniques telles que la mise en commun d’objects sont couramment utilisées pour améliorer les performances du LOH. http://en.wikipedia.org/wiki/Object_pool_pattern

Source: http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

UPDATE: .Net 4.5.1 vous permettra de compacter à la demande le LOH au sein de votre application à l’aide de l’API GC.Collect.