saya masih sangat tidak yakin tentang ini. Saya bekerja sejak 7 tahun di Server Aplikasi. Instalasi kami yang lebih besar menggunakan Ram 24 GB. Multithreaded, dan SEMUA panggilan untuk GC.Collect () mengalami masalah kinerja yang sangat mengerikan.
Banyak Komponen pihak ketiga menggunakan GC.Collect () ketika mereka pikir itu pintar untuk melakukan ini sekarang. Jadi sekelompok sederhana Excel-Report memblokir App Server untuk semua utas beberapa kali dalam satu menit.
Kami harus memperbaiki semua Komponen Pihak ke-3 untuk menghapus panggilan GC.Collect (), dan semua bekerja dengan baik setelah melakukan ini.
Tetapi saya menjalankan Server di Win32 juga, dan di sini saya mulai menggunakan GC.Collect () setelah mendapatkan OutOfMemoryException.
Tetapi saya juga tidak yakin tentang hal ini, karena saya sering memperhatikan, ketika saya mendapatkan OOM pada 32 Bit, dan saya coba lagi untuk menjalankan Operasi yang sama lagi, tanpa memanggil GC.Collect (), itu hanya berfungsi dengan baik.
Satu hal yang saya heran adalah Pengecualian OOM itu sendiri ... Jika saya akan menulis .Net Framework, dan saya tidak dapat mengalokasikan blok memori, saya akan menggunakan GC.Collect (), defrag memory (??), coba lagi , dan jika saya masih tidak dapat menemukan blok memori gratis, maka saya akan membuang OOM-Exception.
Atau setidaknya menjadikan perilaku ini sebagai opsi yang dapat dikonfigurasi, karena kelemahan masalah kinerja dengan GC.Collect.
Sekarang saya punya banyak kode seperti ini di aplikasi saya untuk "menyelesaikan" masalah:
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);
}
(Perhatikan bahwa perilaku Thread.Sleep () adalah perilaku yang benar-benar spesifik untuk aplikasi, karena kami menjalankan Layanan Caching ORM, dan layanan ini membutuhkan waktu untuk melepaskan semua objek yang di-cache, jika RAM melebihi beberapa nilai yang telah ditentukan. Jadi ia menunggu beberapa detik pertama kalinya, dan telah meningkatkan waktu tunggu setiap kemunculan OOM.)