Prevent.NET wywóz śmieci na krótki okres czasu

Mam wysokowydajną aplikację, która obsługuje bardzo dużą ilość danych. Otrzymuje, analizuje i odrzuca ogromne ilości informacji w bardzo krótkim czasie. Powoduje to sporą ilość wyrzucania obiektów, które obecnie próbuję zoptymalizować, ale również powoduje wtórny problem. Kiedy śmieciarka kopie w to może spowodować pewne duże opóźnienia, ponieważ czyści rzeczy (przez długi mam na myśli 10s do 100s milisekund). 99% czasu jest to dopuszczalne, ale przy krótkich oknach czasu około 1-2 minut muszę być absolutnie pewien, że wywóz śmieci nie powoduje opóźnienia. Wiem, kiedy te okresy czasu pojawią się wcześniej i potrzebuję tylko sposobu, aby upewnić się, że wywóz śmieci nie nastąpi w tym okresie. Aplikacja jest napisana w C# przy użyciu. NET 4.0 Framework i używa zarówno zarządzanego, jak i niezarządzanego kodu, jeśli ma to znaczenie.

Moje pytania to;

  1. czy możliwe jest krótkotrwałe wstrzymanie Garbage Collection dla cały program?
  2. czy możliwe jest użycie systemu.GC.Collect() aby wymusić garbage collection przed oknem potrzebuję free of Garbage Collection I jeśli to zrobię, jak długo będę wolny od Garbage Collection?
  3. jakie rady mają ludzie, aby zminimalizować potrzebę zbierania śmieci ogólnie?

Uwaga-Ten system jest dość złożony z wielu różnych komponentów. Mam nadzieję, że uniknę podejścia, w którym będę musiał zaimplementować Niestandardowy IDisposable interfejs na każdym klasy programu.

Author: casperOne, 2011-05-15

2 answers

. NET 4.6 dodał dwie nowe metody: GC.TryStartNoGCRegion oraz GC.EndNoGCRegion tylko za to.

 69
Author: xanatos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-14 10:07:54
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;
}

To pozwoli Ci wyłączyć GC tak bardzo, jak możesz. Nie zrobi żadnych dużych zbiorów obiektów dopóki:

  • dzwonisz GC.Collect()
  • ustawiasz GCSettings.LatencyMode na coś innego niż LowLatency
  • system operacyjny wysyła sygnał o niskiej pamięci do CLR

Należy zachować ostrożność podczas robienia tego, ponieważ zużycie pamięci może wzrosnąć bardzo szybko, gdy jesteś w tym bloku try. Jeśli GC zbiera, robi to z jakiegoś powodu, a Ty powinieneś tylko poważnie rozważ to, jeśli masz dużą ilość pamięci w systemie.

W odniesieniu do pytania trzeciego, być może Możesz spróbować ponownie użyć obiektów, takich jak tablice bajtów, jeśli odbierasz informacje przez We/Wy systemu plików lub sieć? Jeśli przetwarzasz te informacje na niestandardowe klasy, spróbuj ponownie je wykorzystać, ale nie mogę dać zbyt wielu dobrych rad, nie wiedząc więcej o tym, co dokładnie robisz.

Oto kilka artykułów MSDN, które również mogą pomóc:

Uwaga: GCSettings.LatencyMode = GCLatencyMode.LowLatency można ustawić tylko wtedy, gdy GCSettings.IsServerGC == false. IsServerGC można zmienić w App.config:

  <runtime>
    <gcServer enabled="false" />
  </runtime>
 70
Author: Rico Suter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-16 10:49:45