Sdílet prostřednictvím


Garbage Collection-Benachrichtigungen

Aktualisiert: Juli 2008

Es gibt Situationen, in denen eine vollständige Garbage Collection durch die Common Language Runtime die Leistung nachteilig beeinflussen kann. Das kann besonders für Server, die eine große Zahl von Anfragen verarbeiten, ein Problem darstellen. In diesem Fall kann eine lange Garbage Collection einen Anforderungstimout verursachen. Um vollständige Collections in kritischen Zeiträumen zu verhindern, können Sie sich über anstehende Collections benachrichtigen lassen und dann entsprechende Maßnahmen ergreifen, um die Arbeitsauslastung auf eine andere Serverinstanz umzuleiten. Sie können auch selbst eine Collection auslösen, wenn die aktuelle Serverinstanz keine Anfragen verarbeiten muss.

Hinweis:

Dieses Feature ist nur verfügbar, wenn die gleichzeitige Garbage Collection deaktiviert ist. Die gleichzeitige Garbage Collection ist standardmäßig aktiviert, sofern die Ausführung nicht in einer Hostumgebung erfolgt und die Konfiguration vom Host geändert wurde. Die gleichzeitige Garbage Collection ist nicht verfügbar, wenn die Garbage Collection auf dem Server verwendet wird. Diese Funktion unterstützt die gleichzeitige Garbage Collection nicht, da Speicherreservierungen beim Ausführen der gleichzeitigen Garbage Collection zulässig sind. Informationen zum Deaktivieren der gleichzeitigen Garbage Collection finden Sie unter der <gcConcurrent>-Laufzeiteinstellung.

Die RegisterForFullGCNotification-Methode wird für die Auslösung einer Benachrichtigung registriert, wenn die Laufzeit ermittelt, dass eine vollständige Garbage Collection ansteht. Diese Benachrichtigung besteht aus zwei Teilen: dem Anstehen einer vollständigen Garbage Collection und dem Abschluss der vollständigen Garbage Collection.

Verwenden Sie die WaitForFullGCApproach- Methode und WaitForFullGCComplete-Methode, um zu ermitteln, wann eine Benachrichtigung ausgelöst wurde. Sie verwenden diese Methoden normalerweise in einer while-Schleife, um fortlaufend eine GCNotificationStatus-Enumeration mit dem Status der Benachrichtigung zu erhalten. Wenn dieser Wert Succeeded ist, können Sie folgendermaßen vorgehen:

  • Als Reaktion auf eine Benachrichtigung, die mit der WaitForFullGCApproach-Methode abgerufen wurde, können Sie die Arbeitsauslastung umleiten und gegebenenfalls selbst eine Collection auslösen.

  • Als Reaktion auf eine Benachrichtigung, die mit der WaitForFullGCComplete-Methode abgerufen wurde, können Sie die aktuelle Serverinstanz erneut für die Verarbeitung von Anforderungen verfügbar machen. Sie können auch Informationen sammeln. Zum Beispiel können Sie die CollectionCount-Methode verwenden, um die Anzahl der Collections aufzuzeichnen.

Beschreibt, wie die WaitForFullGCApproach-Methode und die WaitForFullGCComplete-Methode zusammenwirken. Wenn Sie eine Methode ohne die andere verwenden, können unbestimmte Ergebnisse auftreten.

Vollständige Garbage Collection

Die Laufzeit veranlasst eine vollständige Garbage Collection, wenn eines der folgenden Szenarien zutrifft:

  • Es wurde genügend Speicher in Generation 2 höher gestuft, um die nächste Collection von Generation 2 auszulösen.

  • Es wurde genügend Speicher in den großen Objektheap höher gestuft, um die nächste Collection der Generation 2 auszulösen.

  • Eine Collection der Generation 1 wird aufgrund anderer Faktoren zu einer Collection der Generation 2 eskaliert.

Die Schwellenwerte, die Sie in der RegisterForFullGCNotification-Methode angeben, gelten für die ersten zwei Szenarios. Im ersten Szenario werden Sie jedoch aus zwei Gründen nicht immer die Benachrichtigung über die den Schwellenwerten entsprechende Zeit erhalten, die Sie festgelegt haben:

  • Die Laufzeit überprüft aus Leistungsgründen nicht jede kleine Objektzuordnung.

  • Nur Collections der Generation 1 stufen Speicher in die Generation 2 herauf.

Das dritte Szenario trägt auch zur Ungewissheit bei, wann Sie die Benachrichtigung empfangen. Obwohl dies keine Garantie ist, ist es doch ein sinnvoller Weg, die Auswirkungen einer unerwünschten vollständigen Garbage Collection zu mindern, indem die Anforderungen während dieser Zeit umgeleitet werden, oder Sie selbst eine Collection vornehmen, wenn diese zeitlich passender ist.

Parameter für den Benachrichtigungsschwellenwert

Die RegisterForFullGCNotification-Methode verfügt über zwei Parameter, die die Schwellenwerte für Objekte der Generation 2 und den Heap für große Objekte festlegt. Wenn diese Werte erfüllt werden, sollte eine Garbage Collection-Benachrichtigung ausgelöst werden. In der folgenden Tabelle werden diese Parameter beschrieben.

Parameter

Beschreibung

maxGenerationThreshold

Eine Zahl zwischen 1 und 99, die auf Grundlage der in die Generation 2 hochgestuften Objekte angibt, wann die Benachrichtigung ausgelöst werden soll.

largeObjectHeapThreshold

Eine Zahl zwischen 1 und 99, die auf Grundlage der im großen Objektheap reservierten Objekte angibt, wann die Benachrichtigung ausgelöst werden soll.

Wenn Sie einen Wert festlegen, der zu hoch ist, erhalten Sie mit hoher Wahrscheinlichkeit eine Benachrichtigung. Es kann jedoch eine zu lange Wartezeit auftreten, bevor die Laufzeit eine Collection veranlasst. Wenn Sie selbst eine Collection auslösen, können Sie mehr Objekte freigeben, als dies bei einer Collection durch die Laufzeit der Fall wäre.

Wenn Sie einen Wert angeben, der zu niedrig ist, veranlasst die Laufzeit möglicherweise eine Collection, bevor Sie eine Benachrichtigung erhalten.

Beispiel

Beschreibung

Im folgenden Beispiel verarbeitet eine Gruppe von Servern eingehende Webanforderungen. Um die Arbeitslast für das Verarbeiten von Anforderungen zu simulieren, werden einer List<T>-Auflistung Bytearrays hinzugefügt. Jeder Server registriert sich für eine Garbage Collection-Benachrichtigung und startet einen Thread für die WaitForFullGCProc-Benutzermethode, um die GCNotificationStatus-Enumeration, die von den WaitForFullGCApproach und den WaitForFullGCComplete Methoden zurückgegeben wird, ständig zu überwachen.

Die WaitForFullGCApproach- Methode und die WaitForFullGCComplete-Methode rufen ihre jeweiligen Benutzermethoden zur Ereignisbehandlung auf, wenn eine Benachrichtigung ausgelöst wird:

  • OnFullGCApproachNotify

    Diese Methode ruft die RedirectRequests-Benutzermethode auf, die den Server für Anforderungswarteschlangen anweist, keine weiteren Anforderungen an den Server zu senden. Dies wird durch Festlegen der Klassenebenenvariable bAllocate auf false simuliert, sodass keine weiteren Objekte zugewiesen werden.

    Danach wird die FinishExistingRequests-Benutzermethode aufgerufen, um die ausstehenden Serveranforderungen zu verarbeiten. Dies wird durch Löschen der List<T>-Auflistung simuliert.

    Schließlich wird eine Garbage Collection veranlasst, da die Arbeitslast gering ist.

  • OfFullGCCompeteNotify

    Diese Methode ruft die AcceptRequests- Benutzermethode dazu auf, wieder Anforderungen anzunehmen, da der Server nicht mehr für eine vollständige Garbage Collection anfällig ist. Diese Aktion wird simuliert, indem die bAllocate-Variable auf true festgelegt wird, sodass Objekte wieder der List<T>-Auflistung zugewiesen werden können.

Der folgende Code enthält die Main-Methode des Beispiels.

' 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

// 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: {0}", 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);
    }
}

Der folgende Code enthält die WaitForFullGCProc-Benutzermethode mit einer kontinuierlichen <legacyBold>While</legacyBold>-Schleife, um eine Überprüfung auf Garbage Collection-Benachrichtigungen durchzuführen.

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 Notifiction 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 Notifiction 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

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 Notifiction 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.
            s = GC.WaitForFullGCComplete();
            if (s == GCNotificationStatus.Succeeded)
            {
                Console.WriteLine("GC Notifiction raised.");
                OnFullGCCompleteEndNotify();
            }
            else if (s == 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;
        }
    }

}

Der folgende Code enthält die OnFullGCApproachNotify-Methode, wie aufgerufen von der

WaitForFullGCProc-Methode.

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 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.");

}

Der folgende Code enthält die OnFullGCApproachComplete-Methode, wie aufgerufen von der

WaitForFullGCProc-Methode.

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 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.");
}

Der folgende Code enthält die Benutzermethoden, die von der OnFullGCApproachNotify-Methode und OnFullGCCompleteNotify-Methode aufgerufen werden. Die Benutzermethode leitet Anforderungen um, schließt vorhandene Anforderungen ab und nimmt Anforderungen wieder auf, nachdem eine vollständige Garbage Collection erfolgt ist.

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;

}

Im Folgenden finden Sie das gesamte Codebeispiel.

Imports System
Imports System.Collections.Generic
Imports System.Threading
Imports Microsoft.VisualBasic



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 Notifiction 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 Notifiction 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
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: {0}", 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 Notifiction 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.
                    s = GC.WaitForFullGCComplete();
                    if (s == GCNotificationStatus.Succeeded)
                    {
                        Console.WriteLine("GC Notifiction raised.");
                        OnFullGCCompleteEndNotify();
                    }
                    else if (s == 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;

        }
    }
}

Siehe auch

Weitere Ressourcen

Garbage Collection

Änderungsprotokoll

Date

Versionsgeschichte

Grund

Juli 2008

Thema hinzugefügt.

SP1-Featureänderung.