J’ai une application très performante qui gère une très grande quantité de données. Il reçoit, parsing et élimine d’énormes quantités d’informations sur de très courtes périodes. Cela provoque une quantité importante de perte d’objects que j’essaie actuellement d’optimiser, mais cela cause également un problème secondaire. Lorsque le nettoyage de la mémoire entre en jeu, cela peut entraîner de longs retards car il nettoie les choses (de 10 à 100 secondes). 99% du temps, cela est acceptable, mais pour des fenêtres de courte durée, environ 1 à 2 minutes, je dois être absolument certain que le nettoyage de la mémoire ne cause pas de retard. Je sais quand ces périodes se produiront à l’avance et j’ai juste besoin d’un moyen de s’assurer que la collecte des ordures ne se produise pas pendant cette période. L’application est écrite en C # à l’aide de .NET Framework 4.0 et utilise du code managé et non géré si cela est important.
Mes questions sont:
Remarque: ce système est assez complexe avec de nombreux composants différents. J’espère éviter 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 vous le pouvez. Il ne fera pas de grandes collections d’objects jusqu’à ce que:
GC.Collect()
GCSettings.LatencyMode
à 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. Si le CPG est en train de collecter, il le fait pour une raison, et vous ne devriez envisager cela sérieusement que si vous avez une grande quantité de mémoire sur votre système.
En référence à la troisième question, vous pouvez peut-être essayer de réutiliser des objects tels que des tableaux d’octets si vous recevez des informations via les E / S du système de fichiers ou un réseau? Si vous parsingz ces informations dans des classes personnalisées, essayez de les réutiliser également, mais je ne peux pas vous donner trop de conseils sans en savoir plus sur ce que vous faites exactement.
Voici quelques articles MSDN qui peuvent aussi 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
: