GC.RegisterForFullGCNotification(Int32, Int32) 메서드
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
조건이 전체 가비지 수집을 선호하는 경우와 수집이 완료된 경우 가비지 수집 알림을 발생시켜야 하며,
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)
매개 변수
- maxGenerationThreshold
- Int32
2세대에 할당된 개체에 따라 알림을 발생시켜야 하는 시기를 지정하는 1에서 99 사이의 숫자입니다.
- largeObjectHeapThreshold
- Int32
큰 개체 힙에 할당된 개체에 따라 알림을 발생시켜야 하는 시기를 지정하는 1에서 99 사이의 숫자입니다.
- 특성
예외
maxGenerationThreshold 또는 largeObjectHeapThreshold 1에서 99 사이가 아닙니다.
동시 가비지 수집을 사용하는 경우 이 멤버를 사용할 수 없습니다. 동시 가비지 수집을 <사용하지 않도록 설정하는 방법에 대한 자세한 내용은 gcConcurrent> 런타임 설정을 참조하세요.
예제
다음 예제에서는 가비지 수집 알림을 등록하고 스레드를 시작하여 가비지 수집 알림의 상태를 모니터링하는 방법을 보여 줍니다. 이 코드 예제는 가비지 수집 알림 토픽에 제공되는 더 큰 예제의 일부입니다.
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
설명
각 세대에 대해 가비지 수집기는 해당 세대에 할당하는 임계값을 설정합니다. 할당 크기가 이 임계값을 초과하면 해당 생성 시 가비지 수집이 트리거됩니다. 예를 들어 2세대의 임계값이 20MB(20MB가 1세대 컬렉션에서 유지되고 2세대로 승격됨)이고 20MB 이상이 1세대에서 살아남았고 2세대로 메시지가 표시되면 다음 가비지 수집이 2세대 컬렉션으로 시도됩니다. 마찬가지로, LOH(큰 개체 힙) 임계값이 20MB이고 앱에서 20MB 이상의 큰 개체를 할당한 경우 다음 가비지 수집도 2세대 컬렉션으로 시도됩니다(LOH는 gen2 가비지 수집에서만 수집되기 때문에).
및 maxGenerationThreshold 임계값은 largeObjectHeapThreshold 전체 가비지 수집이 발생하기 전에 알림을 받은 양을 미리 제어합니다. 임계값이 클수록 알림과 다음 전체 가비지 수집 사이에 발생할 수 있는 할당이 늘어납니다.
공용 언어 런타임에 의한 전체 가비지 수집이 애플리케이션의 성능에 부정적인 영향을 주는 경우 런타임이 전체 가비지 수집을 수행하려고 할 때 알림을 요청하고 조건이 여전히 유리한 경우 컬렉션을 직접 유도하여 Collect 해당 컬렉션을 우회하도록 요청할 수 있습니다. 가비지 수집 일정을 직접 변경하는 것 외에도 전체 GC 알림은 시나리오에 따라 유용합니다.
전체 가비지 수집의 접근 방식을 모니터링하고, 가비지 수집이 다가오고 있다는 알림을 받으면 라이브 데이터 크기(예: 일부 캐시 항목을 해제)를 줄입니다. 따라서 가비지 수집이 발생하면 더 많은 메모리를 회수할 수 있습니다.
일부 통계를 수집할 수 있도록 전체 가비지 수집 완료를 모니터링합니다. 예를 들어 라이브 데이터의 크기를 알 수 있도록 GC 완료 시 힙의 크기를 측정할 수 있습니다. (전체 GC 후 힙은 가장 작은 크기입니다.)
전체 가비지 수집을 나타내는 항목에 대한 자세한 내용은 가비지 수집 알림을 참조하세요.
가비지 수집 알림에 등록할 때 전체 가비지 수집이 가까워지고 완료될 때 알림을 받을 수 있습니다. 이 패턴은 운영 체제가 메모리 부족 알림을 모니터링하는 방식과 유사합니다.
및 maxGenerationThreshold 매개 변수를 지정하려면 largeObjectHeapThreshold 다음 지침을 사용합니다.
임계값이 클수록 알림과 전체 가비지 수집 간에 더 많은 할당이 발생합니다.
임계값이 클수록 런타임에서 접근 중인 컬렉션을 확인할 수 있는 더 많은 기회가 제공됩니다. 이렇게 하면 알림을 받을 가능성이 높아집니다. 그러나 런타임이 다음 컬렉션을 유도하기 전에 더 많은 할당이 발생하므로 임계값을 너무 높게 설정해서는 안 됩니다.
높은 임계값을 사용하여 알림 시 컬렉션을 직접 유도하는 경우 런타임의 다음 컬렉션에서 회수하는 것보다 더 적은 수의 개체가 회수됩니다.
임계값이 작을수록 알림과 전체 가비지 수집 간의 할당이 줄어듭니다.