MemoryFailPoint Clase

Definición

Comprueba si hay suficientes recursos de memoria antes de ejecutar una operación. Esta clase no puede heredarse.

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
Herencia
Implementaciones

Ejemplos

MemoryFailPoint permite que una aplicación se ralente para evitar quedarse sin memoria de una manera dañada. Debe usarse dentro de un ámbito léxico. En el ejemplo siguiente se inician subprocesos para procesar elementos de una cola de trabajo. Antes de iniciar cada subproceso, se comprueban los recursos de memoria disponibles mediante MemoryFailPoint. Si se produce una excepción, el método main espera hasta que la memoria esté disponible antes de iniciar el siguiente subproceso.

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);
    }
}

Comentarios

Nota

Esta clase está pensada para su uso en el desarrollo avanzado.

La creación de una instancia de la MemoryFailPoint clase crea una puerta de memoria. Una puerta de memoria comprueba si hay suficientes recursos antes de iniciar una actividad que requiere una gran cantidad de memoria. Si se produce un error en la comprobación, se produce una InsufficientMemoryException excepción. Esta excepción impide que se inicie una operación y reduce la posibilidad de error debido a la falta de recursos. Esto le permite reducir el rendimiento para evitar una OutOfMemoryException excepción y cualquier daño de estado que pueda resultar de un control incorrecto de la excepción en ubicaciones arbitrarias del código.

Importante

Este tipo implementa la interfaz IDisposable. Cuando haya terminado de utilizar el tipo, debe desecharlo directa o indirectamente. Para eliminar el tipo directamente, llame a su método Dispose en un bloque try/catch. Para deshacerse de él indirectamente, use una construcción de lenguaje como using (en C#) o Using (en Visual Basic). Para más información, vea la sección "Uso de objetos que implementan IDisposable" en el tema de la interfaz IDisposable.

Al producir una InsufficientMemoryException excepción, una aplicación puede distinguir entre una estimación de que una operación no podrá completarse y una operación parcialmente completada que pueda haber dañado el estado de la aplicación. Esto permite a una aplicación reducir la frecuencia de una directiva de escalación pesimista, que puede requerir descargar el proceso actual AppDomain o reciclarlo.

MemoryFailPoint comprueba si hay suficiente memoria y espacio de direcciones virtuales consecutivos disponibles en todos los montones de recolección de elementos no utilizados y puede aumentar el tamaño del archivo de intercambio. MemoryFailPoint no garantiza la disponibilidad a largo plazo de la memoria durante la duración de la puerta, pero los llamadores siempre deben usar el Dispose método para asegurarse de que se liberan los recursos asociados a MemoryFailPoint .

Para usar una puerta de memoria, debe crear un MemoryFailPoint objeto y especificar el número de megabytes (MB) de memoria que se espera que use la siguiente operación. Si no hay suficiente memoria disponible, se produce una InsufficientMemoryException excepción.

El parámetro del constructor debe ser un entero positivo. Un valor negativo genera una ArgumentOutOfRangeException excepción.

MemoryFailPoint funciona con una granularidad de 16 MB. Los valores menores de 16 MB se tratan como 16 MB y otros valores se tratan como el siguiente múltiplo mayor de 16 MB.

Constructores

MemoryFailPoint(Int32)

Inicializa una nueva instancia de la clase MemoryFailPoint, especificando la cantidad de memoria necesaria para una ejecución sin problemas.

Métodos

Dispose()

Libera todos los recursos que usa MemoryFailPoint.

Equals(Object)

Determina si el objeto especificado es igual que el objeto actual.

(Heredado de Object)
Finalize()

Se asegura de que los recursos se liberan y que se llevan a cabo otras operaciones de limpieza cuando el recolector de elementos no utilizados recupere el objeto MemoryFailPoint.

GetHashCode()

Sirve como la función hash predeterminada.

(Heredado de Object)
GetType()

Obtiene el Type de la instancia actual.

(Heredado de Object)
MemberwiseClone()

Crea una copia superficial del Object actual.

(Heredado de Object)
ToString()

Devuelve una cadena que representa el objeto actual.

(Heredado de Object)

Se aplica a