MemoryFailPoint Klasa

Definicja

Sprawdza wystarczającą ilość zasobów pamięci przed wykonaniem operacji. Klasa ta nie może być dziedziczona.

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
Dziedziczenie
Implementuje

Przykłady

MemoryFailPoint Umożliwia aplikacji spowolnienie się, aby uniknąć wyczerpania pamięci w sposób uszkodzony. Powinien być używany w zakresie leksykalnym. Poniższy przykład uruchamia wątki do przetwarzania elementów w kolejce roboczej. Przed uruchomieniem każdego wątku dostępne zasoby pamięci są sprawdzane przy użyciu polecenia MemoryFailPoint. Jeśli zostanie zgłoszony wyjątek, metoda główna czeka, aż pamięć będzie dostępna przed uruchomieniem następnego wątku.

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

Uwagi

Uwaga

Ta klasa jest przeznaczona do użycia w zaawansowanej programowania.

Utworzenie wystąpienia MemoryFailPoint klasy powoduje utworzenie bramy pamięci. Brama pamięci sprawdza wystarczającą ilość zasobów przed zainicjowaniem działania wymagającego dużej ilości pamięci. Niepowodzenie sprawdzania powoduje zgłoszenie wyjątku InsufficientMemoryException . Ten wyjątek uniemożliwia uruchomienie operacji i zmniejsza możliwość niepowodzenia z powodu braku zasobów. Dzięki temu można zmniejszyć wydajność, aby uniknąć OutOfMemoryException wyjątku i wszelkich uszkodzeń stanu, które mogą wynikać z nieprawidłowej obsługi wyjątku w dowolnych lokalizacjach w kodzie.

Ważne

Ten typ implementuje IDisposable interfejs. Po zakończeniu korzystania z typu należy go usunąć bezpośrednio lub pośrednio. Aby usunąć typ bezpośrednio, wywołaj metodę Dispose try/catch w bloku. Aby usunąć go pośrednio, należy użyć konstrukcji językowej, takiej jak using (w języku C#) lub Using (w Visual Basic). Aby uzyskać więcej informacji, zobacz sekcję "Using an Object that Implements IDisposable" (Używanie obiektu implementujące protokół IDisposable) w temacie interfejsu IDisposable .

Zgłaszając InsufficientMemoryException wyjątek, aplikacja może odróżnić oszacowanie, że operacja nie będzie mogła zakończyć się, a częściowo ukończoną operacją, która mogła uszkodzić stan aplikacji. Dzięki temu aplikacja może zmniejszyć częstotliwość pesymistycznych zasad eskalacji, które mogą wymagać zwolnienia bieżącego AppDomain lub recyklingu procesu.

MemoryFailPoint sprawdza, czy ilość pamięci i kolejnej wirtualnej przestrzeni adresowej są dostępne we wszystkich stercie odzyskiwania pamięci i może zwiększyć rozmiar pliku wymiany. MemoryFailPoint nie gwarantuje długoterminowej dostępności pamięci w okresie istnienia bramy, ale osoby wywołujące powinny zawsze używać Dispose metody w celu zapewnienia, że zasoby skojarzone z MemoryFailPoint nimi są zwalniane.

Aby użyć bramy pamięci, należy utworzyć MemoryFailPoint obiekt i określić liczbę megabajtów (MB) pamięci, która ma zostać użyta przez następną operację. Jeśli ilość pamięci jest niedostępna, InsufficientMemoryException zgłaszany jest wyjątek.

Parametr konstruktora musi być dodatnią liczbą całkowitą. Wartość ujemna ArgumentOutOfRangeException zgłasza wyjątek.

MemoryFailPoint działa na poziomie szczegółowości wynoszącym 16 MB. Wszystkie wartości mniejsze niż 16 MB są traktowane jako 16 MB, a inne wartości są traktowane jako kolejna największa wielokrotność 16 MB.

Konstruktory

MemoryFailPoint(Int32)

Inicjuje MemoryFailPoint nowe wystąpienie klasy, określając ilość pamięci wymaganej do pomyślnego wykonania.

Metody

Dispose()

Zwalnia wszelkie zasoby używane przez element MemoryFailPoint.

Equals(Object)

Określa, czy dany obiekt jest taki sam, jak bieżący obiekt.

(Odziedziczone po Object)
Finalize()

Gwarantuje, że zasoby są zwalniane, a inne operacje oczyszczania są wykonywane podczas odzyskiwania obiektu przez moduł odśmiecniania MemoryFailPoint pamięci.

GetHashCode()

Służy jako domyślna funkcja skrótu.

(Odziedziczone po Object)
GetType()

Type Pobiera wartość bieżącego wystąpienia.

(Odziedziczone po Object)
MemberwiseClone()

Tworzy płytkią kopię bieżącego Objectelementu .

(Odziedziczone po Object)
ToString()

Zwraca ciąg reprezentujący bieżący obiekt.

(Odziedziczone po Object)

Dotyczy