MemoryFailPoint Classe

Definizione

Verifica la disponibilità di risorse di memoria sufficienti prima di eseguire un'operazione. La classe non può essere ereditata.

public ref class MemoryFailPoint sealed : System::Runtime::ConstrainedExecution::CriticalFinalizerObject, IDisposable
public sealed class MemoryFailPoint : System.Runtime.ConstrainedExecution.CriticalFinalizerObject, IDisposable
type MemoryFailPoint = class
    inherit CriticalFinalizerObject
    interface IDisposable
Public NotInheritable Class MemoryFailPoint
Inherits CriticalFinalizerObject
Implements IDisposable
Ereditarietà
Implementazioni

Esempio

MemoryFailPoint consente a un'applicazione di rallentare se stessa per evitare l'esaurimento della memoria in modo danneggiato. Deve essere usato all'interno di un ambito lessicale. L'esempio seguente avvia i thread per elaborare gli elementi in una coda di lavoro. Prima dell'avvio di ogni thread, le risorse di memoria disponibili vengono controllate usando MemoryFailPoint. Se viene generata un'eccezione, il metodo principale attende fino a quando la memoria non è disponibile prima di avviare il thread successivo.

using System;
using System.Runtime;
using System.IO;
using System.Threading;
using System.Collections.Generic;
using System.Collections;

class MemoryFailPointExample
{
    // Allocate in chunks of 64 megabytes.
    private const uint chunkSize = 64 << 20;
    // Use more than the total user-available address space (on 32 bit machines)
    // to drive towards getting an InsufficientMemoryException.
    private const uint numWorkItems = 1 + ((1U << 31) / chunkSize);
    static Queue workQueue = new Queue(50);

    // This value can be computed separately and hard-coded into the application.
    // The method is included to illustrate the technique.
    private static int EstimateMemoryUsageInMB()
    {
        int memUsageInMB = 0;

        long memBefore = GC.GetTotalMemory(true);
        int numGen0Collections = GC.CollectionCount(0);
        // Execute a test version of the method to estimate memory requirements.
        // This test method only exists to determine the memory requirements.
        ThreadMethod();
        // Includes garbage generated by the worker function.
        long memAfter = GC.GetTotalMemory(false);
        // If a garbage collection occurs during the measuring, you might need a greater memory requirement.
        Console.WriteLine("Did a GC occur while measuring?  {0}", numGen0Collections == GC.CollectionCount(0));
        // Set the field used as the parameter for the MemoryFailPoint constructor.
        long memUsage = (memAfter - memBefore);
        if (memUsage < 0)
        {
            Console.WriteLine("GC's occurred while measuring memory usage.  Try measuring again.");
            memUsage = 1 << 20;
        }

        // Round up to the nearest MB.
        memUsageInMB = (int)(1 + (memUsage >> 20));
        Console.WriteLine("Memory usage estimate: {0} bytes, rounded to {1} MB", memUsage, memUsageInMB);
        return memUsageInMB;
    }

    static void Main()
    {
        Console.WriteLine("Attempts to allocate more than 2 GB of memory across worker threads.");
        int memUsageInMB = EstimateMemoryUsageInMB();

        // For a production application consider using the threadpool instead.
        Thread[] threads = new Thread[numWorkItems];
        // Create a work queue to be processed by multiple threads.
        int n = 0;
        for (n = 0; n < numWorkItems; n++)
            workQueue.Enqueue(n);
        // Continue to launch threads until the work queue is empty.
        while (workQueue.Count > 0)
        {
            Console.WriteLine(" GC heap (live + garbage): {0} MB", GC.GetTotalMemory(false) >> 20);
            MemoryFailPoint memFailPoint = null;
            try
            {
                // Check for available memory.
                memFailPoint = new MemoryFailPoint(memUsageInMB);
                n = (int)workQueue.Dequeue();
                threads[n] =
                    new Thread(new ParameterizedThreadStart(ThreadMethod));
                WorkerState state = new WorkerState(n, memFailPoint);
                threads[n].Start(state);
                Thread.Sleep(10);
            }
            catch (InsufficientMemoryException e)
            {
                // MemoryFailPoint threw an exception, handle by sleeping for a while,  then
                // continue processing the queue.
                Console.WriteLine("Expected InsufficientMemoryException thrown.  Message: " + e.Message);
                // We could optionally sleep until a running worker thread
                // has finished, like this:  threads[joinCount++].Join();
                Thread.Sleep(1000);
            }
        }

        Console.WriteLine("WorkQueue is empty - blocking to ensure all threads quit (each thread sleeps for 10 seconds)");
        foreach (Thread t in threads)
            t.Join();
        Console.WriteLine("All worker threads are finished - exiting application.");
    }

    // Test version of the working code to determine memory requirements.
    static void ThreadMethod()
    {
        byte[] bytes = new byte[chunkSize];
    }

    internal class WorkerState
    {
        internal int _threadNumber;
        internal MemoryFailPoint _memFailPoint;

        internal WorkerState(int threadNumber, MemoryFailPoint memoryFailPoint)
        {
            _threadNumber = threadNumber;
            _memFailPoint = memoryFailPoint;
        }

        internal int ThreadNumber
        {
            get { return _threadNumber; }
        }

        internal MemoryFailPoint MemoryFailPoint
        {
            get { return _memFailPoint; }
        }
    }

    // The method that does the work.
    static void ThreadMethod(Object o)
    {
        WorkerState state = (WorkerState)o;
        Console.WriteLine("Executing ThreadMethod, " +
            "thread number {0}.", state.ThreadNumber);
        byte[] bytes = null;
        try
        {
            bytes = new byte[chunkSize];
            // Allocated all the memory needed for this workitem.
            // Now dispose of the MemoryFailPoint, then process the workitem.
            state.MemoryFailPoint.Dispose();
        }
        catch (OutOfMemoryException oom)
        {
            Console.Beep();
            Console.WriteLine("Unexpected OutOfMemory exception thrown: " + oom);
        }

        // Do work here, possibly taking a lock if this app needs
        // synchronization between worker threads and/or the main thread.

        // Keep the thread alive for awhile to simulate a running thread.
        Thread.Sleep(10000);

        // A real thread would use the byte[], but to be an illustrative sample,
        // explicitly keep the byte[] alive to help exhaust the memory.
        GC.KeepAlive(bytes);
        Console.WriteLine("Thread {0} is finished.", state.ThreadNumber);
    }
}

Commenti

Nota

Questa classe è destinata all'uso nello sviluppo avanzato.

La creazione di un'istanza della MemoryFailPoint classe crea un gate di memoria. Un gate di memoria controlla le risorse sufficienti prima di avviare un'attività che richiede una grande quantità di memoria. Se il controllo ha esito negativo, viene generata un'eccezione InsufficientMemoryException . Questa eccezione impedisce l'avvio di un'operazione e riduce la possibilità di errore a causa della mancanza di risorse. Ciò consente di ridurre le prestazioni per evitare un'eccezione OutOfMemoryException e qualsiasi danneggiamento dello stato che può causare una gestione errata dell'eccezione in posizioni arbitrarie nel codice.

Importante

Il tipo implementa l'interfaccia IDisposable. Dopo aver utilizzato il tipo, è necessario eliminarlo direttamente o indirettamente. Per eliminare direttamente il tipo, chiamare il metodo Dispose in un blocco try/catch. Per eliminarlo indirettamente, utilizzare un costrutto di linguaggio come ad esempio using in C# o Using in Visual Basic. Per altre informazioni, vedere la sezione "Uso di un oggetto che implementa IDisposable" nell'argomento relativo all'interfaccia IDisposable.

Generando un'eccezione, un'applicazione InsufficientMemoryException può distinguere tra una stima che un'operazione non sarà in grado di completare e un'operazione parzialmente completata che potrebbe aver danneggiato lo stato dell'applicazione. Ciò consente a un'applicazione di ridurre la frequenza di un criterio di escalation pessimistico, che può richiedere lo scarico dell'attuale AppDomain o riciclaggio del processo.

MemoryFailPoint verifica se lo spazio indirizzi virtuale e memoria sufficiente sono disponibili in tutti gli heaps di Garbage Collection e può aumentare le dimensioni del file di scambio. MemoryFailPoint non garantisce alcuna garanzia sulla disponibilità a lungo termine della memoria durante la durata del gate, ma i chiamanti devono sempre usare il Dispose metodo per garantire che le risorse associate a MemoryFailPoint vengano rilasciate.

Per usare un gate di memoria, è necessario creare un MemoryFailPoint oggetto e specificare il numero di megabyte (MB) di memoria che l'operazione successiva deve usare. Se la memoria sufficiente non è disponibile, viene generata un'eccezione InsufficientMemoryException .

Il parametro del costruttore deve essere un intero positivo. Un valore negativo o 0 genera un'eccezione ArgumentOutOfRangeException .

MemoryFailPoint opera a una granularità di 16 MB. Tutti i valori inferiori a 16 MB vengono considerati come 16 MB e altri valori vengono considerati come più grandi più grandi di 16 MB.

Costruttori

MemoryFailPoint(Int32)

Inizializza una nuova istanza della classe MemoryFailPoint, specificando la quantità di memoria richiesta per il completamento dell'esecuzione.

Metodi

Dispose()

Rilascia tutte le risorse usate da MemoryFailPoint.

Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.

(Ereditato da Object)
Finalize()

Garantisce che le risorse vengano liberate e che vengano eseguite le altre operazioni di pulizia quando l'oggetto MemoryFailPoint viene recuperato da Garbage Collector.

GetHashCode()

Funge da funzione hash predefinita.

(Ereditato da Object)
GetType()

Ottiene l'oggetto Type dell'istanza corrente.

(Ereditato da Object)
MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.

(Ereditato da Object)
ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.

(Ereditato da Object)

Si applica a