GC.RegisterForFullGCNotification(Int32, Int32) Methode
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Gibt an, dass eine Garbage Collection-Benachrichtigung ausgelöst werden soll, wenn Bedingungen die vollständige Garbage Collection bevorzugen und wann die Auflistung abgeschlossen wurde.
public:
static void RegisterForFullGCNotification(int maxGenerationThreshold, int largeObjectHeapThreshold);
public static void RegisterForFullGCNotification(int maxGenerationThreshold, int largeObjectHeapThreshold);
[System.Security.SecurityCritical]
public static void RegisterForFullGCNotification(int maxGenerationThreshold, int largeObjectHeapThreshold);
static member RegisterForFullGCNotification : int * int -> unit
[<System.Security.SecurityCritical>]
static member RegisterForFullGCNotification : int * int -> unit
Public Shared Sub RegisterForFullGCNotification (maxGenerationThreshold As Integer, largeObjectHeapThreshold As Integer)
Parameter
- maxGenerationThreshold
- Int32
Eine Zahl zwischen 1 und 99, die angibt, wann die Benachrichtigung basierend auf den Objekten der Generation 2 ausgelöst werden soll.
- largeObjectHeapThreshold
- Int32
Eine Zahl zwischen 1 und 99, die angibt, wann die Benachrichtigung basierend auf Objekten ausgelöst werden soll, die im Heap des großen Objekts zugeordnet sind.
- Attribute
Ausnahmen
maxGenerationThreshold oder largeObjectHeapThreshold liegt nicht zwischen 1 und 99.
Dieses Element ist nicht verfügbar, wenn gleichzeitige Garbage Collection aktiviert ist. Informationen zum Deaktivieren der gleichzeitigen Garbage Collection finden Sie in der <gcConcurrent-Laufzeiteinstellung> .
Beispiele
Das folgende Beispiel zeigt, wie Sie eine Garbage Collection-Benachrichtigung registrieren und einen Thread starten, um den Status der Garbage Collection-Benachrichtigung zu überwachen. Dieses Codebeispiel ist Teil eines größeren Beispiels, das für garbage Collection Notifications thema bereitgestellt wird.
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 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;
}
}
}
open System
open System.Threading
// Variable for continual checking in the
// While loop in the WaitForFullGCProc method.
let mutable 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.
let mutable bAllocate = false
// Variable for ending the example.
let mutable finalExit = false
// Collection for objects that simulate the server request workload.
let load = ResizeArray<byte []>()
let redirectRequests () =
// Code that sends requests
// to other servers.
// Suspend work.
bAllocate <- false
let finishExistingRequests () =
// Code that waits a period of time
// for pending requests to finish.
// Clear the simulated workload.
load.Clear()
let acceptRequests () =
// Code that resumes processing
// requests on this server.
// Resume work.
bAllocate <- true
let onFullGCApproachNotify () =
printfn "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()
printfn "Induced a collection."
let onFullGCCompleteEndNotify () =
// Method that informs the request queuing server
// that this server is ready to accept requests again.
acceptRequests ()
printfn "Accepting requests again."
let waitForFullGCProc () =
let mutable broken = false
while not broken do
let mutable broken = false
// CheckForNotify is set to true and false in Main.
while checkForNotify && not broken do
// Check for a notification of an approaching collection.
match GC.WaitForFullGCApproach() with
| GCNotificationStatus.Succeeded ->
printfn "GC Notification raised."
onFullGCApproachNotify ()
// Check for a notification of a completed collection.
match GC.WaitForFullGCComplete() with
| GCNotificationStatus.Succeeded ->
printfn "GC Notification raised."
onFullGCCompleteEndNotify ()
| GCNotificationStatus.Canceled ->
printfn "GC Notification cancelled."
broken <- true
| _ ->
// Could be a time out.
printfn "GC Notification not applicable."
broken <- true
| GCNotificationStatus.Canceled ->
printfn "GC Notification cancelled."
broken <- true
| _ ->
// This can occur if a timeout period
// is specified for WaitForFullGCApproach(Timeout)
// or WaitForFullGCComplete(Timeout)
// and the time out period has elapsed.
printfn "GC Notification not applicable."
broken <- true
Thread.Sleep 500
// FinalExit is set to true right before
// the main thread cancelled notification.
if finalExit then broken <- true
try
// Register for a notification.
GC.RegisterForFullGCNotification(10, 10)
printfn "Registered for GC notification."
checkForNotify <- true
bAllocate <- true
// Start a thread using WaitForFullGCProc.
let thWaitForFullGC = Thread(ThreadStart waitForFullGCProc)
thWaitForFullGC.Start()
// While the thread is checking for notifications in
// WaitForFullGCProc, create objects to simulate a server workload.
try
let mutable lastCollCount = 0
let mutable newCollCount = 0
let mutable broken = false
while not broken do
if bAllocate then
load.Add(Array.zeroCreate<byte> 1000)
newCollCount <- GC.CollectionCount 2
if newCollCount <> lastCollCount then
// Show collection count when it increases:
printfn $"Gen 2 collection count: {GC.CollectionCount(2)}"
lastCollCount <- newCollCount
// For ending the example (arbitrary).
if newCollCount = 500 then
finalExit <- true
checkForNotify <- false
broken <- true
with :? OutOfMemoryException -> printfn "Out of memory."
finalExit <- true
checkForNotify <- false
GC.CancelFullGCNotification()
with :? InvalidOperationException as invalidOp ->
printfn $"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 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
Hinweise
Für jede Generation legt der Garbage Collector einen Schwellenwert für zuordnungen in diese Generation fest. Wenn die Größe der Zuordnungen diesen Schwellenwert überschreitet, wird eine Garbage Collection für diese Generation ausgelöst. Wenn z. B. der Schwellenwert der Generation 2 20 MB beträgt (was bedeutet, dass 20 MB Sammlungen der Generation 1 überlebt und in die Generation 2 höhergestuft wird) und mehr als 20 MB die Generation 1 überstanden hat und zur Generation 2 aufgefordert wird, wird die nächste Garbage Collection als Sammlung der Generation 2 versucht. Wenn der Heap-Schwellenwert für große Objekte (LOH) auf 20 MB festgelegt ist und Ihre App mehr als 20 MB große Objekte zugewiesen hat, wird auch die nächste Garbage Collection als Generation 2-Auflistung versucht (da der LOH nur in Gen2 Garbage Collections erfasst wird).
Die maxGenerationThreshold Schwellenwerte largeObjectHeapThreshold steuern, wie viel Im Voraus Sie benachrichtigt werden, bevor eine vollständige Garbage Collection auftritt. Je größer der Schwellenwert ist, desto mehr Zuordnungen können zwischen der Benachrichtigung und der nächsten vollständigen Garbage Collection auftreten.
Wenn Sie Situationen haben, in denen eine vollständige Garbage Collection durch die Common Language Runtime die Leistung Ihrer Anwendung beeinträchtigen würde, können Sie aufgefordert werden, benachrichtigt zu werden, wenn die Laufzeit in der Lage ist, eine vollständige Garbage Collection zu erledigen und diese Sammlung zu umgehen, indem Sie eine Sammlung selbst (mithilfe der Collect Methode) erziehen, wenn die Bedingungen weiterhin günstig sind. Neben dem Selbstwechseln des Garbage Collection-Zeitplans ist die vollständige GC-Benachrichtigung in den folgenden Szenarien hilfreich:
Sie überwachen den Ansatz einer vollständigen Garbage Collection, und wenn Sie benachrichtigt werden, dass eins nähert, verringern Sie die Größe von Livedaten (z. B. indem Sie einige Cacheeinträge freigeben). Wenn die Garbage Collection auftritt, kann sie daher mehr Arbeitsspeicher freigeben.
Sie überwachen den Abschluss einer vollständigen Garbage Collection, damit Sie einige Statistiken sammeln können. Sie können z. B. die Größe des Heaps bei GC-Abschluss messen, damit Sie die Größe von Livedaten kennen. (Nach einer vollständigen GC ist der Heap auf seiner kleinsten Größe.)
Weitere Informationen dazu, was eine vollständige Garbage Collection darstellt, finden Sie unter Garbage Collection Notifications.
Wenn Sie sich für eine Garbage Collection-Benachrichtigung registrieren, können Sie benachrichtigt werden, wenn sich eine vollständige Garbage Collection nähert und wann sie abgeschlossen ist. Dieses Muster ähnelt der Überwachung des Betriebssystems auf Benachrichtigungen mit geringem Arbeitsspeicher.
Verwenden Sie die folgenden Richtlinien zum Angeben der maxGenerationThreshold Parameter largeObjectHeapThreshold :
Je größer der Schwellenwert ist, desto mehr Zuordnungen erfolgen zwischen der Benachrichtigung und der vollständigen Garbage Collection.
Ein größerer Schwellenwert bietet mehr Möglichkeiten für die Laufzeit, nach einer näherenden Sammlung zu suchen. Dies erhöht die Wahrscheinlichkeit, dass Sie benachrichtigt werden. Sie sollten den Schwellenwert jedoch nicht zu hoch festlegen, da dies zu einer weiteren Zuordnung führt, bevor die Laufzeit die nächste Sammlung auslöst.
Wenn Sie eine Sammlung bei der Benachrichtigung mit einem hohen Schwellenwert selbst auslösen, werden weniger Objekte zurückgefordert, als von der nächsten Sammlung der Laufzeit beansprucht würden.
Je kleiner der Schwellenwert, desto weniger Zuweisungen zwischen Benachrichtigung und vollständiger Garbage Collection.