Я все еще не уверен в этом. Я работаю с 7 лет на сервере приложений. Наши большие установки используют оперативную память объемом 24 ГБ. Его многопоточный и ВСЕ вызовы для GC.Collect () столкнулись с действительно ужасными проблемами производительности.
Многие Сторонние Компоненты использовали GC.Collect (), когда они думали, что это было разумно сделать это прямо сейчас. Таким образом, простая группа Excel-отчетов блокировала сервер приложений для всех потоков несколько раз в минуту.
Нам пришлось провести рефакторинг всех сторонних компонентов, чтобы удалить вызовы GC.Collect (), и после этого все работало нормально.
Но я также использую Серверы на Win32, и здесь я начал активно использовать GC.Collect () после получения исключения OutOfMemoryException.
Но я также довольно неуверен в этом, потому что я часто замечал, что когда я получаю OOM на 32-битной системе, и я снова пытаюсь запустить ту же операцию, не вызывая GC.Collect (), она просто работает нормально.
Одна вещь, которая меня интересует, это само исключение OOM ... Если бы я написал .Net Framework и не смог бы выделить блок памяти, я бы использовал GC.Collect (), дефрагментировал память (??), попробуйте снова , и если я все еще не могу найти свободный блок памяти, то я бы выбросил OOM-Exception.
Или, по крайней мере, сделайте это поведение настраиваемым параметром из-за недостатков производительности, связанных с 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.)