Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Common Language Runtime tarafından yapılan tam çöp toplama (yani, nesil 2 koleksiyonu) performansı olumsuz etkileyebileceği durumlar vardır. Bu durum, özellikle büyük hacimli istekleri işleyen sunucular için bir sorun olabilir; bu durumda, uzun süren bir çöp toplama isteğin zaman aşımına neden olabilir. Tam bir çöp toplamanın kritik bir süreçte gerçekleşmesini önlemek için, yaklaşmakta olan tam bir çöp toplama konusunda bilgilendirilebilirsiniz ve ardından iş yükünü başka bir sunucu örneğine yönlendirmek için harekete geçebilirsiniz. Geçerli sunucu örneğinin istekleri işlemesi gerekmemesi koşuluyla, bir koleksiyonu kendiniz de oluşturabilirsiniz.
yöntemi, RegisterForFullGCNotification çalışma zamanı tam çöp toplamanın yaklaştığını algıladığında bir bildirimin yükseltilmesi için kaydeder. Bu bildirimin iki bölümü vardır: tam çöp toplama yaklaştığında ve tam çöp toplama tamamlandığında.
Uyarı
<gcConcurrent> Yapılandırma öğesi etkinleştirildiğinde, WaitForFullGCComplete tam GC arka plan GC olarak yapıldıysa döndürebilirNotApplicableGCNotificationStatus.
Bildirimin ne zaman yükseltildiğini belirlemek için WaitForFullGCApproach ve WaitForFullGCComplete yöntemlerini kullanın. Genellikle, bildirimin durumunu gösteren bir whileGCNotificationStatus numaralandırmayı sürekli almak için döngüde bu yöntemleri kullanırsınız. Bu değer ise Succeededaşağıdakileri yapabilirsiniz:
yöntemiyle WaitForFullGCApproach alınan bir bildirime yanıt olarak, iş yükünü yeniden yönlendirebilir ve muhtemelen bir toplama sürecini kendiniz başlatabilirsiniz.
yöntemiyle alınan bir bildirime WaitForFullGCComplete yanıt olarak, geçerli sunucu örneğini istekleri yeniden işlemek için kullanılabilir hale getirebilirsiniz. Ayrıca bilgi toplayabilirsiniz. Örneğin, yöntemini kullanarak CollectionCount koleksiyon sayısını kaydedebilirsiniz.
WaitForFullGCApproach ve WaitForFullGCComplete yöntemleri birlikte çalışacak şekilde tasarlanmıştır. Birini diğerini kullanmadan kullanmak belirsiz sonuçlara neden olabilir.
Tam Çöp Toplama
Çalışma zamanı, aşağıdaki senaryolardan herhangi biri doğru olduğunda tam çöp toplamaya neden olur:
Yeni nesil 2 koleksiyonuna neden olmak için yeterli bellek 2. nesile yükseltildi.
Yeni nesil 2 koleksiyonuna neden olacak kadar bellek büyük nesne yığınına yükseltildi.
1. nesil bir koleksiyon, diğer faktörlerden dolayı 2. nesil bir koleksiyona yükseltilir.
yönteminde RegisterForFullGCNotification belirttiğiniz eşikler ilk iki senaryo için geçerlidir. Ancak ilk senaryoda, iki nedenden dolayı belirttiğiniz eşik değerleriyle orantılı olarak bildirimi her zaman almazsınız:
Çalışma zamanı her küçük nesne ayırmasını denetlemez (performans nedeniyle).
Yalnızca 1. nesil koleksiyonlar belleği 2. nesil olarak yükselter.
Üçüncü senaryo, bildirimi ne zaman alacağınız belirsizliğe de katkıda bulunur. Bu bir garanti olmasa da, bu süre boyunca istekleri yeniden yönlendirerek veya daha iyi barındırılabilmesi için koleksiyonu kendiniz başlatarak, uygunsuz bir tam çöp toplamanın etkilerini azaltmak için yararlı bir yol olduğunu gösterir.
Bildirim Eşiği Parametreleri
yöntemi, RegisterForFullGCNotification 2. nesil nesnelerin eşik değerlerini ve büyük nesne yığınını belirtmek için iki parametreye sahiptir. Bu değerler karşılandığında bir çöp toplama bildirimi oluşturulmalıdır. Aşağıdaki tabloda bu parametreler açıklanmaktadır.
| Parametre | Açıklama |
|---|---|
maxGenerationThreshold |
1 ile 99 arasında, 2. nesilde yükseltilen nesnelere göre bildirimin ne zaman yükseltilmesi gerektiğini belirten bir sayı. |
largeObjectHeapThreshold |
Büyük nesne yığınında ayrılan nesnelere göre bildirimin ne zaman yükseltilmesi gerektiğini belirten 1 ile 99 arasında bir sayı. |
Çok yüksek bir değer belirtirseniz, bildirim alma olasılığınız yüksektir, ancak çalışma zamanının koleksiyona neden olması için beklenecek süre çok uzun olabilir. Bir koleksiyonu kendiniz başlatırsanız, çalışma zamanının bir koleksiyona neden olduğu durumdan daha fazla nesne geri kazanabilirsiniz.
Çok düşük bir değer belirtirseniz, çalışma zamanı yeterli süreniz olmadan bildirim almanızdan önce koleksiyonu başlatabilir.
Örnek
Açıklama
Aşağıdaki örnekte, gelen Web isteklerine hizmet eden bir sunucu grubu. İşleme isteklerinin iş yükünü simüle etmek için, bayt dizileri bir List<T> koleksiyona eklenir. Her sunucu bir çöp toplama bildirimine kaydolur ve ardından WaitForFullGCProc kullanıcı yönteminde, GCNotificationStatus ve WaitForFullGCApproach yöntemleri tarafından döndürülen WaitForFullGCComplete numaralandırmayı sürekli izlemek için bir iş parçacığı başlatır.
WaitForFullGCApproach ve WaitForFullGCComplete yöntemleri, bir bildirim gönderildiğinde ilgili olay işleme kullanıcı yöntemlerini çağırır:
OnFullGCApproachNotifyBu yöntem, istek kuyruğa alma sunucusuna sunucuya istek göndermeyi askıya almasını isteyen kullanıcı yöntemini çağırır
RedirectRequests. Bu, sınıf düzeyi değişkenibAllocatefalseolarak ayarlanarak simüle edilir, böylece başka nesneler ayrılmaz.Ardından,
FinishExistingRequestsbekleyen sunucu isteklerini işlemeyi tamamlamak için kullanıcı yöntemi çağrılır. Bu, List<T> koleksiyonu temizlenerek simüle edilir.Son olarak, iş yükü hafif olduğundan bir çöp toplama gerçekleştirilir.
OnFullGCCompleteNotifySunucu artık tam çöp toplamaya duyarlı olmadığından, bu yöntem istekleri kabul etmeye devam etmek için kullanıcı yöntemini
AcceptRequestsçağırır. Bu eylem, nesnelerinbAllocatekoleksiyonuna eklenmeye devam edebilmesi içintruedeğişkeninin List<T> olarak ayarlanmasıyla simüle edilir.
Aşağıdaki kod, örneğin yöntemini içerir Main .
public static void Main(string[] args)
{
try
{
// Register for a notification.
GC.RegisterForFullGCNotification(10, 10);
Console.WriteLine("Registered for GC notification.");
checkForNotify = true;
bAllocate = true;
// Start a thread using WaitForFullGCProc.
Thread thWaitForFullGC = new Thread(new ThreadStart(WaitForFullGCProc));
thWaitForFullGC.Start();
// While the thread is checking for notifications in
// WaitForFullGCProc, create objects to simulate a server workload.
try
{
int lastCollCount = 0;
int newCollCount = 0;
while (true)
{
if (bAllocate)
{
load.Add(new byte[1000]);
newCollCount = GC.CollectionCount(2);
if (newCollCount != lastCollCount)
{
// Show collection count when it increases:
Console.WriteLine($"Gen 2 collection count: {GC.CollectionCount(2).ToString()}");
lastCollCount = newCollCount;
}
// For ending the example (arbitrary).
if (newCollCount == 500)
{
finalExit = true;
checkForNotify = false;
break;
}
}
}
}
catch (OutOfMemoryException)
{
Console.WriteLine("Out of memory.");
}
finalExit = true;
checkForNotify = false;
GC.CancelFullGCNotification();
}
catch (InvalidOperationException invalidOp)
{
Console.WriteLine("GC Notifications are not supported while concurrent GC is enabled.\n"
+ invalidOp.Message);
}
}
Imports System.Collections.Generic
Imports System.Threading
Class Program
' Variables for continual checking in the
' While loop in the WaitForFullGcProc method.
Private Shared checkForNotify As Boolean = False
' Variable for suspending work
' (such as servicing allocated server requests)
' after a notification is received and then
' resuming allocation after inducing a garbage collection.
Private Shared bAllocate As Boolean = False
' Variable for ending the example.
Private Shared finalExit As Boolean = False
' Collection for objects that
' simulate the server request workload.
Private Shared load As New List(Of Byte())
Public Shared Sub Main(ByVal args() As String)
Try
' Register for a notification.
GC.RegisterForFullGCNotification(10, 10)
Console.WriteLine("Registered for GC notification.")
bAllocate = True
checkForNotify = True
' Start a thread using WaitForFullGCProc.
Dim thWaitForFullGC As Thread = _
New Thread(New ThreadStart(AddressOf WaitForFullGCProc))
thWaitForFullGC.Start()
' While the thread is checking for notifications in
' WaitForFullGCProc, create objects to simulate a server workload.
Try
Dim lastCollCount As Integer = 0
Dim newCollCount As Integer = 0
While (True)
If bAllocate = True Then
load.Add(New Byte(1000) {})
newCollCount = GC.CollectionCount(2)
If (newCollCount <> lastCollCount) Then
' Show collection count when it increases:
Console.WriteLine("Gen 2 collection count: {0}", _
GC.CollectionCount(2).ToString)
lastCollCount = newCollCount
End If
' For ending the example (arbitrary).
If newCollCount = 500 Then
finalExit = True
checkForNotify = False
bAllocate = False
Exit While
End If
End If
End While
Catch outofMem As OutOfMemoryException
Console.WriteLine("Out of memory.")
End Try
finalExit = True
checkForNotify = False
GC.CancelFullGCNotification()
Catch invalidOp As InvalidOperationException
Console.WriteLine("GC Notifications are not supported while concurrent GC is enabled." _
& vbLf & invalidOp.Message)
End Try
End Sub
Public Shared Sub OnFullGCApproachNotify()
Console.WriteLine("Redirecting requests.")
' Method that tells the request queuing
' server to not direct requests to this server.
RedirectRequests()
' Method that provides time to
' finish processing pending requests.
FinishExistingRequests()
' This is a good time to induce a GC collection
' because the runtime will induce a ful GC soon.
' To be very careful, you can check precede with a
' check of the GC.GCCollectionCount to make sure
' a full GC did not already occur since last notified.
GC.Collect()
Console.WriteLine("Induced a collection.")
End Sub
Public Shared Sub OnFullGCCompleteEndNotify()
' Method that informs the request queuing server
' that this server is ready to accept requests again.
AcceptRequests()
Console.WriteLine("Accepting requests again.")
End Sub
Public Shared Sub WaitForFullGCProc()
While True
' CheckForNotify is set to true and false in Main.
While checkForNotify
' Check for a notification of an approaching collection.
Dim s As GCNotificationStatus = GC.WaitForFullGCApproach
If (s = GCNotificationStatus.Succeeded) Then
Console.WriteLine("GC Notification raised.")
OnFullGCApproachNotify()
ElseIf (s = GCNotificationStatus.Canceled) Then
Console.WriteLine("GC Notification cancelled.")
Exit While
Else
' This can occur if a timeout period
' is specified for WaitForFullGCApproach(Timeout)
' or WaitForFullGCComplete(Timeout)
' and the time out period has elapsed.
Console.WriteLine("GC Notification not applicable.")
Exit While
End If
' Check for a notification of a completed collection.
s = GC.WaitForFullGCComplete
If (s = GCNotificationStatus.Succeeded) Then
Console.WriteLine("GC Notification raised.")
OnFullGCCompleteEndNotify()
ElseIf (s = GCNotificationStatus.Canceled) Then
Console.WriteLine("GC Notification cancelled.")
Exit While
Else
' Could be a time out.
Console.WriteLine("GC Notification not applicable.")
Exit While
End If
End While
Thread.Sleep(500)
' FinalExit is set to true right before
' the main thread cancelled notification.
If finalExit Then
Exit While
End If
End While
End Sub
Private Shared Sub RedirectRequests()
' Code that sends requests
' to other servers.
' Suspend work.
bAllocate = False
End Sub
Private Shared Sub FinishExistingRequests()
' Code that waits a period of time
' for pending requests to finish.
' Clear the simulated workload.
load.Clear()
End Sub
Private Shared Sub AcceptRequests()
' Code that resumes processing
' requests on this server.
' Resume work.
bAllocate = True
End Sub
End Class
Aşağıdaki kod, çöp toplama bildirimlerini denetlemek için sürekli bir while döngüsü içeren kullanıcı yöntemini içerir WaitForFullGCProc .
public static void WaitForFullGCProc()
{
while (true)
{
// CheckForNotify is set to true and false in Main.
while (checkForNotify)
{
// Check for a notification of an approaching collection.
GCNotificationStatus s = GC.WaitForFullGCApproach();
if (s == GCNotificationStatus.Succeeded)
{
Console.WriteLine("GC Notification raised.");
OnFullGCApproachNotify();
}
else if (s == GCNotificationStatus.Canceled)
{
Console.WriteLine("GC Notification cancelled.");
break;
}
else
{
// This can occur if a timeout period
// is specified for WaitForFullGCApproach(Timeout)
// or WaitForFullGCComplete(Timeout)
// and the time out period has elapsed.
Console.WriteLine("GC Notification not applicable.");
break;
}
// Check for a notification of a completed collection.
GCNotificationStatus status = GC.WaitForFullGCComplete();
if (status == GCNotificationStatus.Succeeded)
{
Console.WriteLine("GC Notification raised.");
OnFullGCCompleteEndNotify();
}
else if (status == GCNotificationStatus.Canceled)
{
Console.WriteLine("GC Notification cancelled.");
break;
}
else
{
// Could be a time out.
Console.WriteLine("GC Notification not applicable.");
break;
}
}
Thread.Sleep(500);
// FinalExit is set to true right before
// the main thread cancelled notification.
if (finalExit)
{
break;
}
}
}
Public Shared Sub WaitForFullGCProc()
While True
' CheckForNotify is set to true and false in Main.
While checkForNotify
' Check for a notification of an approaching collection.
Dim s As GCNotificationStatus = GC.WaitForFullGCApproach
If (s = GCNotificationStatus.Succeeded) Then
Console.WriteLine("GC Notification raised.")
OnFullGCApproachNotify()
ElseIf (s = GCNotificationStatus.Canceled) Then
Console.WriteLine("GC Notification cancelled.")
Exit While
Else
' This can occur if a timeout period
' is specified for WaitForFullGCApproach(Timeout)
' or WaitForFullGCComplete(Timeout)
' and the time out period has elapsed.
Console.WriteLine("GC Notification not applicable.")
Exit While
End If
' Check for a notification of a completed collection.
s = GC.WaitForFullGCComplete
If (s = GCNotificationStatus.Succeeded) Then
Console.WriteLine("GC Notification raised.")
OnFullGCCompleteEndNotify()
ElseIf (s = GCNotificationStatus.Canceled) Then
Console.WriteLine("GC Notification cancelled.")
Exit While
Else
' Could be a time out.
Console.WriteLine("GC Notification not applicable.")
Exit While
End If
End While
Thread.Sleep(500)
' FinalExit is set to true right before
' the main thread cancelled notification.
If finalExit Then
Exit While
End If
End While
End Sub
Aşağıdaki kod, OnFullGCApproachNotify yönteminin çağrıldığı şekliyle içerir.
WaitForFullGCProc yöntem.
public static void OnFullGCApproachNotify()
{
Console.WriteLine("Redirecting requests.");
// Method that tells the request queuing
// server to not direct requests to this server.
RedirectRequests();
// Method that provides time to
// finish processing pending requests.
FinishExistingRequests();
// This is a good time to induce a GC collection
// because the runtime will induce a full GC soon.
// To be very careful, you can check precede with a
// check of the GC.GCCollectionCount to make sure
// a full GC did not already occur since last notified.
GC.Collect();
Console.WriteLine("Induced a collection.");
}
Public Shared Sub OnFullGCApproachNotify()
Console.WriteLine("Redirecting requests.")
' Method that tells the request queuing
' server to not direct requests to this server.
RedirectRequests()
' Method that provides time to
' finish processing pending requests.
FinishExistingRequests()
' This is a good time to induce a GC collection
' because the runtime will induce a ful GC soon.
' To be very careful, you can check precede with a
' check of the GC.GCCollectionCount to make sure
' a full GC did not already occur since last notified.
GC.Collect()
Console.WriteLine("Induced a collection.")
End Sub
Aşağıdaki kod, OnFullGCApproachComplete yönteminin çağrıldığı şekliyle içerir.
WaitForFullGCProc yöntem.
public static void OnFullGCCompleteEndNotify()
{
// Method that informs the request queuing server
// that this server is ready to accept requests again.
AcceptRequests();
Console.WriteLine("Accepting requests again.");
}
Public Shared Sub OnFullGCCompleteEndNotify()
' Method that informs the request queuing server
' that this server is ready to accept requests again.
AcceptRequests()
Console.WriteLine("Accepting requests again.")
End Sub
Aşağıdaki kod, OnFullGCApproachNotify ve OnFullGCCompleteNotify yöntemlerinden çağrılan kullanıcı yöntemlerini içerir. Kullanıcı yöntemleri istekleri yeniden yönlendirir, var olan istekleri tamamlar ve tam çöp toplama işlemi gerçekleştikten sonra istekleri sürdürür.
private static void RedirectRequests()
{
// Code that sends requests
// to other servers.
// Suspend work.
bAllocate = false;
}
private static void FinishExistingRequests()
{
// Code that waits a period of time
// for pending requests to finish.
// Clear the simulated workload.
load.Clear();
}
private static void AcceptRequests()
{
// Code that resumes processing
// requests on this server.
// Resume work.
bAllocate = true;
}
Private Shared Sub RedirectRequests()
' Code that sends requests
' to other servers.
' Suspend work.
bAllocate = False
End Sub
Private Shared Sub FinishExistingRequests()
' Code that waits a period of time
' for pending requests to finish.
' Clear the simulated workload.
load.Clear()
End Sub
Private Shared Sub AcceptRequests()
' Code that resumes processing
' requests on this server.
' Resume work.
bAllocate = True
End Sub
Kod örneğinin tamamı aşağıdaki gibidir:
using System;
using System.Collections.Generic;
using System.Threading;
namespace GCNotify
{
class Program
{
// Variable for continual checking in the
// While loop in the WaitForFullGCProc method.
static bool checkForNotify = false;
// Variable for suspending work
// (such servicing allocated server requests)
// after a notification is received and then
// resuming allocation after inducing a garbage collection.
static bool bAllocate = false;
// Variable for ending the example.
static bool finalExit = false;
// Collection for objects that
// simulate the server request workload.
static List<byte[]> load = new List<byte[]>();
public static void Main(string[] args)
{
try
{
// Register for a notification.
GC.RegisterForFullGCNotification(10, 10);
Console.WriteLine("Registered for GC notification.");
checkForNotify = true;
bAllocate = true;
// Start a thread using WaitForFullGCProc.
Thread thWaitForFullGC = new Thread(new ThreadStart(WaitForFullGCProc));
thWaitForFullGC.Start();
// While the thread is checking for notifications in
// WaitForFullGCProc, create objects to simulate a server workload.
try
{
int lastCollCount = 0;
int newCollCount = 0;
while (true)
{
if (bAllocate)
{
load.Add(new byte[1000]);
newCollCount = GC.CollectionCount(2);
if (newCollCount != lastCollCount)
{
// Show collection count when it increases:
Console.WriteLine($"Gen 2 collection count: {GC.CollectionCount(2).ToString()}");
lastCollCount = newCollCount;
}
// For ending the example (arbitrary).
if (newCollCount == 500)
{
finalExit = true;
checkForNotify = false;
break;
}
}
}
}
catch (OutOfMemoryException)
{
Console.WriteLine("Out of memory.");
}
finalExit = true;
checkForNotify = false;
GC.CancelFullGCNotification();
}
catch (InvalidOperationException invalidOp)
{
Console.WriteLine("GC Notifications are not supported while concurrent GC is enabled.\n"
+ invalidOp.Message);
}
}
public static void OnFullGCApproachNotify()
{
Console.WriteLine("Redirecting requests.");
// Method that tells the request queuing
// server to not direct requests to this server.
RedirectRequests();
// Method that provides time to
// finish processing pending requests.
FinishExistingRequests();
// This is a good time to induce a GC collection
// because the runtime will induce a full GC soon.
// To be very careful, you can check precede with a
// check of the GC.GCCollectionCount to make sure
// a full GC did not already occur since last notified.
GC.Collect();
Console.WriteLine("Induced a collection.");
}
public static void OnFullGCCompleteEndNotify()
{
// Method that informs the request queuing server
// that this server is ready to accept requests again.
AcceptRequests();
Console.WriteLine("Accepting requests again.");
}
public static void WaitForFullGCProc()
{
while (true)
{
// CheckForNotify is set to true and false in Main.
while (checkForNotify)
{
// Check for a notification of an approaching collection.
GCNotificationStatus s = GC.WaitForFullGCApproach();
if (s == GCNotificationStatus.Succeeded)
{
Console.WriteLine("GC Notification raised.");
OnFullGCApproachNotify();
}
else if (s == GCNotificationStatus.Canceled)
{
Console.WriteLine("GC Notification cancelled.");
break;
}
else
{
// This can occur if a timeout period
// is specified for WaitForFullGCApproach(Timeout)
// or WaitForFullGCComplete(Timeout)
// and the time out period has elapsed.
Console.WriteLine("GC Notification not applicable.");
break;
}
// Check for a notification of a completed collection.
GCNotificationStatus status = GC.WaitForFullGCComplete();
if (status == GCNotificationStatus.Succeeded)
{
Console.WriteLine("GC Notification raised.");
OnFullGCCompleteEndNotify();
}
else if (status == GCNotificationStatus.Canceled)
{
Console.WriteLine("GC Notification cancelled.");
break;
}
else
{
// Could be a time out.
Console.WriteLine("GC Notification not applicable.");
break;
}
}
Thread.Sleep(500);
// FinalExit is set to true right before
// the main thread cancelled notification.
if (finalExit)
{
break;
}
}
}
private static void RedirectRequests()
{
// Code that sends requests
// to other servers.
// Suspend work.
bAllocate = false;
}
private static void FinishExistingRequests()
{
// Code that waits a period of time
// for pending requests to finish.
// Clear the simulated workload.
load.Clear();
}
private static void AcceptRequests()
{
// Code that resumes processing
// requests on this server.
// Resume work.
bAllocate = true;
}
}
}
Imports System.Collections.Generic
Imports System.Threading
Class Program
' Variables for continual checking in the
' While loop in the WaitForFullGcProc method.
Private Shared checkForNotify As Boolean = False
' Variable for suspending work
' (such as servicing allocated server requests)
' after a notification is received and then
' resuming allocation after inducing a garbage collection.
Private Shared bAllocate As Boolean = False
' Variable for ending the example.
Private Shared finalExit As Boolean = False
' Collection for objects that
' simulate the server request workload.
Private Shared load As New List(Of Byte())
Public Shared Sub Main(ByVal args() As String)
Try
' Register for a notification.
GC.RegisterForFullGCNotification(10, 10)
Console.WriteLine("Registered for GC notification.")
bAllocate = True
checkForNotify = True
' Start a thread using WaitForFullGCProc.
Dim thWaitForFullGC As Thread = _
New Thread(New ThreadStart(AddressOf WaitForFullGCProc))
thWaitForFullGC.Start()
' While the thread is checking for notifications in
' WaitForFullGCProc, create objects to simulate a server workload.
Try
Dim lastCollCount As Integer = 0
Dim newCollCount As Integer = 0
While (True)
If bAllocate = True Then
load.Add(New Byte(1000) {})
newCollCount = GC.CollectionCount(2)
If (newCollCount <> lastCollCount) Then
' Show collection count when it increases:
Console.WriteLine("Gen 2 collection count: {0}", _
GC.CollectionCount(2).ToString)
lastCollCount = newCollCount
End If
' For ending the example (arbitrary).
If newCollCount = 500 Then
finalExit = True
checkForNotify = False
bAllocate = False
Exit While
End If
End If
End While
Catch outofMem As OutOfMemoryException
Console.WriteLine("Out of memory.")
End Try
finalExit = True
checkForNotify = False
GC.CancelFullGCNotification()
Catch invalidOp As InvalidOperationException
Console.WriteLine("GC Notifications are not supported while concurrent GC is enabled." _
& vbLf & invalidOp.Message)
End Try
End Sub
Public Shared Sub OnFullGCApproachNotify()
Console.WriteLine("Redirecting requests.")
' Method that tells the request queuing
' server to not direct requests to this server.
RedirectRequests()
' Method that provides time to
' finish processing pending requests.
FinishExistingRequests()
' This is a good time to induce a GC collection
' because the runtime will induce a ful GC soon.
' To be very careful, you can check precede with a
' check of the GC.GCCollectionCount to make sure
' a full GC did not already occur since last notified.
GC.Collect()
Console.WriteLine("Induced a collection.")
End Sub
Public Shared Sub OnFullGCCompleteEndNotify()
' Method that informs the request queuing server
' that this server is ready to accept requests again.
AcceptRequests()
Console.WriteLine("Accepting requests again.")
End Sub
Public Shared Sub WaitForFullGCProc()
While True
' CheckForNotify is set to true and false in Main.
While checkForNotify
' Check for a notification of an approaching collection.
Dim s As GCNotificationStatus = GC.WaitForFullGCApproach
If (s = GCNotificationStatus.Succeeded) Then
Console.WriteLine("GC Notification raised.")
OnFullGCApproachNotify()
ElseIf (s = GCNotificationStatus.Canceled) Then
Console.WriteLine("GC Notification cancelled.")
Exit While
Else
' This can occur if a timeout period
' is specified for WaitForFullGCApproach(Timeout)
' or WaitForFullGCComplete(Timeout)
' and the time out period has elapsed.
Console.WriteLine("GC Notification not applicable.")
Exit While
End If
' Check for a notification of a completed collection.
s = GC.WaitForFullGCComplete
If (s = GCNotificationStatus.Succeeded) Then
Console.WriteLine("GC Notification raised.")
OnFullGCCompleteEndNotify()
ElseIf (s = GCNotificationStatus.Canceled) Then
Console.WriteLine("GC Notification cancelled.")
Exit While
Else
' Could be a time out.
Console.WriteLine("GC Notification not applicable.")
Exit While
End If
End While
Thread.Sleep(500)
' FinalExit is set to true right before
' the main thread cancelled notification.
If finalExit Then
Exit While
End If
End While
End Sub
Private Shared Sub RedirectRequests()
' Code that sends requests
' to other servers.
' Suspend work.
bAllocate = False
End Sub
Private Shared Sub FinishExistingRequests()
' Code that waits a period of time
' for pending requests to finish.
' Clear the simulated workload.
load.Clear()
End Sub
Private Shared Sub AcceptRequests()
' Code that resumes processing
' requests on this server.
' Resume work.
bAllocate = True
End Sub
End Class