Я все еще не уверен в этом.
Я работаю с 7 лет на сервере приложений. Наши большие установки используют 24 ГБ оперативной памяти. Его многопоточный и ВСЕ вызовы для GC.Collect () столкнулись с действительно ужасными проблемами с производительностью.
Многие сторонние Компоненты использовали GC.Collect (), когда они думали, что было бы разумно сделать это прямо сейчас.
Таким образом, простая группа Excel-отчетов блокировала сервер приложений для всех потоков несколько раз в минуту.
Нам пришлось провести рефакторинг всех сторонних компонентов, чтобы удалить вызовы GC.Collect (), и после этого все работало нормально.
Но я также запускаю Серверы на Win32, и здесь я начал активно использовать GC.Collect () после получения исключения OutOfMemoryException.
Но я также довольно неуверен в этом, потому что я часто замечал, что когда я получаю OOM на 32-битной системе, и я снова пытаюсь выполнить ту же операцию, не вызывая GC.Collect (), она просто работает нормально.
Одна вещь, которая меня интересует, это само исключение OOM ...
Если бы я написал .Net Framework, и я не могу выделить блок памяти, я бы использовал GC.Collect (), дефрагментировать память (??), попробуйте еще раз, и если я все еще не могу найти свободный блок памяти, тогда я бы бросил OOM-исключение.
Или, по крайней мере, сделайте это поведение настраиваемым параметром из-за недостатков производительности, связанных с GC.Collect.
Теперь в моем приложении много такого кода, чтобы «решить» проблему:
public static TResult ExecuteOOMAware<T1, T2, TResult>(Func<T1,T2 ,TResult> func, T1 a1, T2 a2)
{
int oomCounter = 0;
int maxOOMRetries = 10;
do
{
try
{
return func(a1, a2);
}
catch (OutOfMemoryException)
{
oomCounter++;
if (maxOOMRetries > 10)
{
throw;
}
else
{
Log.Info("OutOfMemory-Exception caught, Trying to fix. Counter: " + oomCounter.ToString());
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(oomCounter * 10));
GC.Collect();
}
}
} while (oomCounter < maxOOMRetries);
// never gets hitted.
return default(TResult);
}
(Обратите внимание, что поведение Thread.Sleep () действительно специфично для приложения, поскольку мы запускаем службу кэширования ORM, и службе требуется некоторое время для освобождения всех кэшированных объектов, если объем оперативной памяти превышает некоторые предопределенные значения. он ждет несколько секунд в первый раз и увеличивает время ожидания при каждом появлении OOM.)