MemoryFailPoint Classe

Definição

Verifica se há recursos suficientes de memória antes de executar uma operação. Essa classe não pode ser herdada.

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
Herança
Implementações

Exemplos

MemoryFailPoint permite que um aplicativo se desacelere para evitar ficar sem memória de maneira corrompida. Ele deve ser usado dentro de um escopo léxico. O exemplo a seguir inicia threads para processar itens em uma fila de trabalho. Antes de cada thread ser iniciado, os recursos de memória disponíveis são verificados usando MemoryFailPoint. Se uma exceção for gerada, o método principal aguardará até que a memória esteja disponível antes de iniciar o próximo thread.

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

Comentários

Observação

Essa classe destina-se a ser usada em desenvolvimento avançado.

Criar uma instância da MemoryFailPoint classe cria um portão de memória. Uma porta de memória verifica se há recursos suficientes antes de iniciar uma atividade que requer uma grande quantidade de memória. Falha na verificação resulta na geração de uma exceção InsufficientMemoryException . Essa exceção impede que uma operação seja iniciada e reduz a possibilidade de falha devido à falta de recursos. Isso permite que você diminua o desempenho para evitar uma OutOfMemoryException exceção e qualquer corrupção de estado que possa resultar da manipulação inadequada da exceção em locais arbitrários em seu código.

Importante

Esse tipo implementa a interface IDisposable. Quando você terminar de usar o tipo, deverá descartá-lo direta ou indiretamente. Para descartar o tipo diretamente, chame o método Dispose dele em um bloco try/catch. Para descartá-lo indiretamente, use um constructo de linguagem como using ( em C#) ou Using (em Visual Basic). Saiba mais na seção "Como usar um objeto que implementa IDisposable" no tópico da interface IDisposable.

Ao lançar uma exceção InsufficientMemoryException , um aplicativo pode distinguir entre uma estimativa de que uma operação não será capaz de ser concluída e uma operação parcialmente concluída que pode ter corrompido o estado do aplicativo. Isso permite que um aplicativo reduza a frequência de uma política de escalonamento pessimista, o que pode exigir o descarregamento do processo atual AppDomain ou de reciclagem.

MemoryFailPoint verifica se memória suficiente e espaço de endereço virtual consecutivo estão disponíveis em todos os heaps de coleta de lixo e podem aumentar o tamanho do arquivo de troca. MemoryFailPoint não oferece garantias sobre a disponibilidade de longo prazo da memória durante o tempo de vida do portão, mas os chamadores devem sempre usar o método para garantir que os Dispose recursos associados MemoryFailPoint sejam liberados.

Para usar uma porta de memória, você deve criar um MemoryFailPoint objeto e especificar o número de megabytes (MB) de memória que a próxima operação deverá usar. Se memória suficiente não estiver disponível, uma exceção InsufficientMemoryException será gerada.

O parâmetro do construtor deve ser um inteiro positivo. Um valor negativo gera uma exceção ArgumentOutOfRangeException .

MemoryFailPoint opera com uma granularidade de 16 MB. Todos os valores menores que 16 MB são tratados como 16 MB e outros valores são tratados como o próximo maior múltiplo de 16 MB.

Construtores

MemoryFailPoint(Int32)

Inicializa uma nova instância da classe MemoryFailPoint, especificando a quantidade de memória necessária para uma execução bem-sucedida.

Métodos

Dispose()

Libera todos os recursos usados pelo MemoryFailPoint.

Equals(Object)

Determina se o objeto especificado é igual ao objeto atual.

(Herdado de Object)
Finalize()

Garante que os recursos são liberados e outras operações de limpeza são executadas quando o coletor de lixo recupera o objeto MemoryFailPoint.

GetHashCode()

Serve como a função de hash padrão.

(Herdado de Object)
GetType()

Obtém o Type da instância atual.

(Herdado de Object)
MemberwiseClone()

Cria uma cópia superficial do Object atual.

(Herdado de Object)
ToString()

Retorna uma cadeia de caracteres que representa o objeto atual.

(Herdado de Object)

Aplica-se a