Ainda estou bastante inseguro sobre isso. Trabalho há 7 anos em um servidor de aplicativos. Nossas instalações maiores utilizam RAM de 24 GB. Suas chamadas altamente multithreaded e ALL para GC.Collect () tiveram problemas de desempenho realmente terríveis.
Muitos componentes de terceiros usaram o GC.Collect () quando acharam que era inteligente fazer isso agora. Portanto, um simples grupo de relatórios do Excel bloqueou o servidor de aplicativos para todos os threads várias vezes por minuto.
Tivemos que refatorar todos os componentes de terceiros para remover as chamadas GC.Collect () e tudo funcionou bem depois disso.
Mas também estou executando servidores no Win32 e aqui comecei a usar muito o GC.Collect () depois de obter uma OutOfMemoryException.
Mas também não tenho certeza sobre isso, porque muitas vezes notei que quando recebo um OOM em 32 bits e tento executar a mesma operação novamente, sem chamar GC.Collect (), funcionou bem.
Uma coisa que me pergunto é a própria exceção do OOM ... Se eu tivesse escrito o .Net Framework e não posso alocar um bloco de memória, usaria GC.Collect (), desfragmentar a memória (??), tente novamente , e se ainda não consigo encontrar um bloco de memória livre, lançaria a exceção OOM.
Ou, pelo menos, torne esse comportamento como opção configurável, devido às desvantagens do problema de desempenho com o GC.Collect.
Agora eu tenho muitos códigos como este no meu aplicativo para "resolver" o problema:
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);
}
(Observe que o comportamento Thread.Sleep () é realmente um aplicativo específico para aplicativos, porque estamos executando um serviço de armazenamento em cache ORM, e o serviço leva algum tempo para liberar todos os objetos em cache, se a RAM exceder alguns valores predefinidos. alguns segundos na primeira vez e aumentou o tempo de espera a cada ocorrência de OOM.)