.NETを使用してWebファームを実行しています。各Webサーバーは、メモリ内に相当量の静的オブジェクトを保持しています。 Gen 2ガベージコレクション(GC)は10〜20秒かかり、5分ごとに実行されます。 StackOverflowと同じ問題が多かれ少なかれ実行されました。http://samsaffron.com/archive/2011/10/28/in-managed-code-we-trust-our-recent-battles-with-the-net-garbage-collectorガベージコレクションの通知がありません
現時点では、キャッシュ内のオブジェクトの数を減らしています。ただし、これには時間がかかります。
同時に、私たちは、hereに記載されたメソッドを実装して、.NETでのGC接近に関する通知を取得しました。 目的は、GCが近づいているときにファームからWebサーバーを取り出し、GCが終了した後にファームに組み込むことです。 しかし、私たちはすべてのGCの0.7%の通知のみを受け取ります。 maxGenerationThresholdとlargeObjectHeapThresholdは8です。他のしきい値を試しましたが、欠落しているGCの量は変更されませんでした。
同時サーバーガベージコレクション(http://msdn.microsoft.com/en-us/library/ms229357.aspx)を使用しています。 GCLatencyModeはインタラクティブです(http://msdn.microsoft.com/en-us/library/system.runtime.gclatencymode.aspx参照)。ここでもまた、他のGCモード(ワークステーションモード、バッチなど)を使用しようとしました。そして、我々はGCの大半について通知を受けなかった。
何か間違っているのですか、発生するすべてのGCについて通知を受け取ることができませんか? 通知の数を増やすにはどうすればよいですか?
http://assets.red-gate.com/community/books/assets/Under_the_Hood_of_.NET_Management.pdfによると、Gen2が〜10 MBに達するとGCがトリガされます。私たちにはたくさんのRAMがあります。このしきい値を手動でより高いレベルに設定することができれば、このしきい値に達するまでにはもっと時間がかかります。このしきい値を変更する方法はありますか?
このレジスタと通知をリッスンするコードである:
GC.RegisterForFullGCNotification(gcThreshold, gcThreshold);
// Start a thread using WaitForFullGCProc.
thWaitForFullGC = new Thread(WaitForFullGCProc);
thWaitForFullGC.Name = "HealthTestGCNotificationListenerThread (Threshold=" + gcThreshold + ")";
thWaitForFullGC.IsBackground = true;
WaitForFullGCProc():
private void WaitForFullGCProc()
{
try
{
while (!gcAbort)
{
// Check for a notification of an approaching collection.
GCNotificationStatus s;
do
{
int timeOut = CheckForMissedGc() > 0 ? 5000 : (10 * 60 * 1000);
s = GC.WaitForFullGCApproach(timeOut);
if (this.GcState == GCState.InducedUnnotified)
{
// Set the GcState back to okay to prevent the message from staying in the ApplicationMonitoring.
this.GcState = GCState.Okay;
}
} while (s == GCNotificationStatus.Timeout);
if (s == GCNotificationStatus.Succeeded)
{
SetGcState(GCState.Approaching, "GC is approaching..");
gcApproachNotificationCount++;
}
else
{
...
}
Stopwatch stopwatch = Stopwatch.StartNew();
s = GC.WaitForFullGCComplete((int)PrewarnTime.TotalMilliseconds);
long elapsed = stopwatch.ElapsedMilliseconds;
if (s == GCNotificationStatus.Timeout)
{
if (this.ForceGCWhenApproaching && !this.IsInGc && !this.IsPeriodicGcApproaching)
{
this.IsInGc = true;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true);
GC.WaitForPendingFinalizers();
elapsed = stopwatch.ElapsedMilliseconds;
this.IsInGc = false;
}
}
}
gcAbort = false;
}
catch (Exception e)
{
}
}
でそれを購読しますか? – Alex
'GC.RegisterForFullGCNotification(gcThreshold、gcThreshold); // WaitForFullGCProcを使用してスレッドを開始します。 thWaitForFullGC =新しいスレッド(WaitForFullGCProc); thWaitForFullGC.Name = "HealthTestGCNotificationListenerThread(Threshold =" + gcThreshold + ")"; thWaitForFullGC。 IsBackground = true; – kopernik