Gestire le notifiche del Garbage Collector con il .NET Framework 3.5 SP1

di Ugo Lattanzi, in .NET Framework,

Una delle principali caratteristiche del .NET Framework risiede nel fatto che noi sviluppatori non dobbiamo preoccuparci di liberare blocchi di memoria utilizzati dalla nostra applicazione in quanto questo arduo compito è svolto egregiamente dal Garbage Collector.
Precedentemente all'uscita del Service Pack 1 per il Framework 3.5, non avevamo modo di sapere quando il Garbage Collector svolgeva il suo lavoro.
Fortunatamente tutto ciò ora ci è reso possibile grazie ad una serie di Metodi (RegisterForFullGCNotification, WaitForFullGCApproach, GCNotificationStatus, ecc) che sono stati aggiunti alla classe System.GC.

Per poter sfruttare questa nuova caratteristica del Garbage Collector per prima cosa è necessario disabilitare la Concurret (concorrenza) del GC tramite file di configurazione come mostrato dal codice seguente:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <gcConcurrent enabled="false" />
  </runtime>
</configuration>

Per raggiungere lo scopo dell'esempio e poter ricevere le notifiche è necessario che i metodi per monitorare il GC (WaitForFullGCApproach e WaitForFullGCComplete) vengano invocati su un Thread separato da thread principale come mostrato dallo snippet seguente:

private static readonly List<byte[]> load = new List<byte[]>();

private static void Main(string[] args)
{
    GC.RegisterForFullGCNotification(10, 10);

    var monitorThread = new Thread(MonitorGC) {IsBackground = true};
    monitorThread.Start();

    LoadData();

    Console.WriteLine("Press any key to terminate");
    Console.ReadLine();

    GC.CancelFullGCNotification();
}

private static void LoadData()
{
    for (int x = 0; x < 1000000; x++)
        load.Add(new byte[1000]);
}

private static void MonitorGC()
{
    while (true)
    {
        GCNotificationStatus status = GC.WaitForFullGCApproach();
        Console.WriteLine("GC approach: {0}", status);

        status = GC.WaitForFullGCComplete();
        Console.WriteLine("GC complete: {0}", status);
    }
}

Come si può vedere il codice è piuttosto semplice; per prima cosa è necessario comunicare al GC di inviarci una notifica quando effettua un'operazione, e questo è possibile tramite il metodo RegisterForFullGCNotification.
Da qui è necessario creare un ciclo infinito in un Thread Separato (MonitorGC nel nostro esempio) che invocherà i metodi WaitForFullGCApproach e WaitForFullGCComplete necessari a capire lo stato del GC ed infine, tramite il metodo CancelFullGCNotification, dire al GC di non invarci più nessuna notifica, quindi sospendere la richiesta precedente effettuata dal metodo RegisterForFullGCNotification.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Nessuna risorsa collegata

I più letti di oggi