GC.RegisterForFullGCNotification(Int32, Int32) Methode
Definitie
Belangrijk
Bepaalde informatie heeft betrekking op een voorlopige productversie die aanzienlijk kan worden gewijzigd voordat deze wordt uitgebracht. Microsoft biedt geen enkele expliciete of impliciete garanties met betrekking tot de informatie die hier wordt verstrekt.
Hiermee geeft u op dat er een melding voor de garbagecollection moet worden gegenereerd wanneer de voorwaarden de volledige garbagecollection bevorderen en wanneer de verzameling is voltooid.
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)
Parameters
- maxGenerationThreshold
- Int32
Een getal tussen 1 en 99 dat aangeeft wanneer de melding moet worden gegenereerd op basis van de objecten die in generatie 2 zijn toegewezen.
- largeObjectHeapThreshold
- Int32
Een getal tussen 1 en 99 dat aangeeft wanneer de melding moet worden gegenereerd op basis van objecten die zijn toegewezen in de grote object-heap.
- Kenmerken
Uitzonderingen
maxGenerationThreshold of largeObjectHeapThreshold ligt niet tussen 1 en 99.
Dit lid is niet beschikbaar wanneer gelijktijdige garbagecollection is ingeschakeld. Zie de <gcConcurrent> runtime-instelling voor informatie over het uitschakelen van gelijktijdige garbagecollection.
Voorbeelden
In het volgende voorbeeld ziet u hoe u een garbagecollectionmelding registreert en een thread start om de status van de garbagecollectionmelding te bewaken. Dit codevoorbeeld maakt deel uit van een groter voorbeeld voor het onderwerp Garbagecollection-meldingen .
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
Opmerkingen
Voor elke generatie stelt de garbagecollector een drempelwaarde in voor toewijzingen in die generatie. Wanneer de grootte van toewijzingen deze drempelwaarde overschrijdt, wordt een garbagecollection geactiveerd voor die generatie. Als de drempelwaarde van generatie 2 bijvoorbeeld 20 MB is (wat betekent dat 20 MB verzamelingen van generatie 1 overleeft en wordt gepromoveerd tot generatie 2), en meer dan 20 MB de 1e generatie heeft overleefd en wordt gevraagd naar generatie 2, wordt de volgende garbagecollection uitgevoerd als een verzameling van de tweede generatie. Als de drempelwaarde van de grote object heap (LOH) 20 MB is en uw app meer dan 20 MB aan grote objecten heeft toegewezen, wordt de volgende garbagecollection ook uitgevoerd als een verzameling van de tweede generatie (omdat de LOH alleen wordt verzameld in gen2 garbagecollection).
De maxGenerationThreshold drempelwaarden bepalen largeObjectHeapThreshold hoeveel van tevoren u op de hoogte wordt gesteld voordat een volledige garbagecollection plaatsvindt. Hoe groter de drempelwaarde, hoe meer toewijzingen kunnen optreden tussen meldingen en de volgende volledige garbagecollection.
Als u situaties hebt waarin een volledige garbagecollection door de algemene taalruntime de prestaties van uw toepassing nadelig zou beïnvloeden, kunt u vragen om een melding te ontvangen wanneer de runtime op het punt staat om een volledige garbagecollection uit te voeren en deze verzameling te omzeilen door een verzameling zelf (met behulp van de Collect methode) te veroorzaken wanneer de voorwaarden nog steeds gunstig zijn. Naast het zelf wijzigen van het garbagecollectionschema, is volledige GC-melding handig in het volgen van de scenario's:
U controleert op de benadering van een volledige garbagecollection en, wanneer u een melding ontvangt dat er een nadert, verkleint u de livegegevensgrootte (bijvoorbeeld door enkele cachevermeldingen vrij te geven). Als de garbagecollection zich voordoet, kan het daardoor meer geheugen vrijmaken.
U controleert op de voltooiing van een volledige garbagecollection, zodat u enkele statistieken kunt verzamelen. U kunt bijvoorbeeld de grootte van de heap bij GC-voltooiing meten, zodat u de grootte van livegegevens weet. (Na een volledige GGC bevindt de heap zich op zijn kleinste grootte.)
Zie Meldingen voor garbagecollection voor meer informatie over wat een volledige garbagecollection vertegenwoordigt.
Wanneer u zich registreert voor een garbagecollectionmelding, kunt u een melding ontvangen wanneer een volledige garbagecollection nadert en wanneer deze is voltooid. Dit patroon lijkt op hoe het besturingssysteem controleert op meldingen met weinig geheugen.
Gebruik de volgende richtlijnen voor het opgeven van de maxGenerationThreshold en largeObjectHeapThreshold parameters:
Hoe groter de drempelwaarde, hoe meer toewijzingen er plaatsvinden tussen de melding en de volledige garbagecollection.
Een hogere drempelwaarde biedt meer mogelijkheden voor de runtime om te controleren op een naderende verzameling. Dit verhoogt de kans dat u een melding ontvangt. U moet de drempelwaarde echter niet te hoog instellen, omdat dit resulteert in een meer toewijzingen voordat de runtime de volgende verzameling veroorzaakt.
Wanneer u een verzameling zelf opleid bij een melding met behulp van een hoge drempelwaarde, worden er minder objecten vrijgemaakt dan zou worden vrijgemaakt door de volgende verzameling van de runtime.
Hoe kleiner de drempelwaarde, hoe minder toewijzingen tussen meldingen en de volledige garbagecollection.