J'ai une application hautes performances qui gère une très grande quantité de données. Il reçoit, analyse et rejette d'énormes quantités d'informations sur de très courtes périodes. Cela provoque une bonne quantité de désabonnement d'objets que j'essaie actuellement d'optimiser, mais cela provoque également un problème secondaire. Lorsque Garbage Collection entre en action, il peut entraîner de longs retards car il nettoie les choses (j'entends par 10 à 100 secondes de millisecondes). 99% du temps, cela est acceptable, mais pour de brèves périodes de temps d'environ 1 à 2 minutes, je dois être absolument sûr que Garbage Collection ne provoque pas de retard. Je sais quand ces périodes se produiront à l'avance et j'ai juste besoin d'un moyen de m'assurer que la collecte des ordures ne se produit pas pendant cette période. L'application est écrite en C # à l'aide de .NET 4.0 Framework et utilise du code managé et non managé si cela est important.
Mes questions sont;
Remarque - ce système est assez complexe avec de nombreux composants différents. J'espère éviter d'aller vers une approche où je dois implémenter une interface IDisposable personnalisée sur chaque classe du programme.
.NET 4.6 a ajouté deux nouvelles méthodes: GC.TryStartNoGCRegion
et GC.EndNoGCRegion
juste pour cela.
GCLatencyMode oldMode = GCSettings.LatencyMode;
// Make sure we can always go to the catch block,
// so we can set the latency mode back to `oldMode`
RuntimeHelpers.PrepareConstrainedRegions();
try
{
GCSettings.LatencyMode = GCLatencyMode.LowLatency;
// Generation 2 garbage collection is now
// deferred, except in extremely low-memory situations
}
finally
{
// ALWAYS set the latency mode back
GCSettings.LatencyMode = oldMode;
}
Cela vous permettra de désactiver le GC autant que possible. Il ne fera pas de grandes collections d'objets jusqu'à ce que:
GC.Collect()
GCSettings.LatencyMode
Sur autre chose que LowLatency
Soyez prudent lorsque vous faites cela, car l'utilisation de la mémoire peut grimper extrêmement rapidement lorsque vous êtes dans ce bloc try
. Si le GC collecte, il le fait pour une raison, et vous ne devriez sérieusement considérer cela que si vous avez une grande quantité de mémoire sur votre système.
En référence à la question trois, vous pouvez peut-être essayer de réutiliser des objets comme des tableaux d'octets si vous recevez des informations via les E/S du système de fichiers ou un réseau? Si vous analysez ces informations dans des classes personnalisées, essayez de les réutiliser aussi, mais je ne peux pas donner trop de bons conseils sans en savoir plus sur ce que vous faites exactement.
Voici quelques articles MSDN qui peuvent également vous aider:
PrepareConstrainedRegions()
) Remarque: GCSettings.LatencyMode = GCLatencyMode.LowLatency
Ne peut être défini que si GCSettings.IsServerGC == false
. IsServerGC
peut être modifié dans App.config
:
<runtime>
<gcServer enabled="false" />
</runtime>