bu konuda hala emin değilim. 7 yıldan beri bir Uygulama Sunucusunda çalışıyorum. Daha büyük kurulumlarımız 24 GB RAM kullanıyor. Çok iş parçacıklı ve TÜM GC.Collect () çağrıları gerçekten korkunç performans sorunlarıyla karşılaştı.
Birçok üçüncü taraf Bileşeni, şu anda bunu yapmanın akıllıca olduğunu düşündüklerinde GC.Collect () yöntemini kullanmıştır. Bu nedenle, basit bir Excel Rapor grubu, App Server'ı dakikada birkaç kez tüm iş parçacıkları için engelledi.
GC.Collect () çağrılarını kaldırmak için tüm 3. Taraf Bileşenlerini yeniden düzenlemek zorunda kaldık ve bunu yaptıktan sonra hepsi iyi çalıştı.
Ama ben de Win32 üzerinde sunucuları çalıştırıyorum ve burada bir OutOfMemoryException aldıktan sonra GC.Collect () yoğun kullanmaya başladı.
Ama ben de bu konuda oldukça emin değilim, çünkü sık sık fark ettim, 32 Bit'de bir OOM aldığımda ve GC.Collect () çağırmadan aynı Operasyonu tekrar çalıştırmayı denediğimde, gayet iyi çalıştı.
Ben merak ediyorum bir şey OOM İstisna kendisi ... .Net Framework yazmış ve bir bellek bloğu atayamazsanız, ben GC.Collect (), bellek dolandırmak (??) kullanmak, tekrar deneyin ve eğer hala bir boş hafıza bloğu bulamazsam, o zaman OOM-İstisnasını atarım.
Veya GC.Collect ile performans sorununun dezavantajları nedeniyle en azından bu davranışı yapılandırılabilir seçenek olarak yapın.
Şimdi sorunu "çözmek" için benim app böyle kod bir sürü var:
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);
}
(Bir ORM Önbellekleme Hizmeti çalıştırdığımızdan ve RAM'in önceden tanımlanmış bazı değerleri aşması durumunda hizmetin önbelleğe alınmış tüm nesneleri serbest bırakması biraz zaman aldığından Thread.Sleep () davranışının gerçekte Uygulamaya özgü bir davranış olduğunu unutmayın. birkaç saniye ilk kez ve her OOM oluşumunda bekleme süresini artırdı.)