MemoryFailPoint Klasse

Definition

Sucht vor dem Ausführen eines Vorgangs nach ausreichenden Arbeitsspeicherressourcen. Diese Klasse kann nicht vererbt werden.

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
Vererbung
Implementiert

Beispiele

MemoryFailPoint ermöglicht es einer Anwendung, sich zu verlangsamen, um zu vermeiden, dass der Arbeitsspeicher beschädigt ist. Er sollte innerhalb eines lexikalischen Bereichs verwendet werden. Im folgenden Beispiel werden Threads gestartet, um Elemente in einer Arbeitswarteschlange zu verarbeiten. Bevor jeder Thread gestartet wird, werden die verfügbaren Speicherressourcen mithilfe MemoryFailPointvon . Wenn eine Ausnahme ausgelöst wird, wartet die Hauptmethode, bis der Arbeitsspeicher verfügbar ist, bevor der nächste Thread gestartet wird.

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

Hinweise

Note

Diese Klasse ist für die Verwendung in der erweiterten Entwicklung vorgesehen.

Beim Erstellen einer Instanz der MemoryFailPoint Klasse wird ein Speichergater erstellt. Ein Speichergater sucht nach ausreichendEn Ressourcen, bevor eine Aktivität initiiert wird, die eine große Menge an Arbeitsspeicher erfordert. Wenn die Überprüfung fehlschlägt, wird eine InsufficientMemoryException Ausnahme ausgelöst. Diese Ausnahme verhindert, dass ein Vorgang gestartet wird, und verringert die Möglichkeit eines Fehlers aufgrund fehlender Ressourcen. Auf diese Weise können Sie die Leistung verringern, um eine OutOfMemoryException Ausnahme und alle Zustandsbeschädigungen zu vermeiden, die aufgrund einer fehlerhaften Behandlung der Ausnahme an beliebigen Stellen in Ihrem Code auftreten können.

Important

Dieser Typ implementiert die IDisposable Schnittstelle. Nach Abschluss der Verwendung sollten Sie den Typ entweder direkt oder indirekt löschen. Rufen Sie die Methode Dispose in einem try/catch-Block auf, um den Typ direkt zu entsorgen. Verwenden Sie zum indirekten Löschen ein Sprachkonstrukt wie using (in C#) oder Using (in Visual Basic). Weitere Informationen finden Sie im Abschnitt "Verwenden eines Objekts, das IDisposable implementiert" im IDisposable Schnittstellenthema.

Durch Auslösen einer InsufficientMemoryException Ausnahme kann eine Anwendung zwischen einer Schätzung unterscheiden, dass ein Vorgang nicht abgeschlossen werden kann, und einem teilweise abgeschlossenen Vorgang, der möglicherweise den Anwendungsstatus beschädigt hat. Dies ermöglicht es einer Anwendung, die Häufigkeit einer pessimistischen Eskalationsrichtlinie zu verringern, die das Entladen des Stroms AppDomain oder das Recycling des Prozesses erfordern kann.

MemoryFailPoint überprüft, ob genügend Arbeitsspeicher und aufeinanderfolgender virtueller Adressraum in allen Garbage Collection-Heaps verfügbar sind, und kann die Größe der Auslagerungsdatei erhöhen. MemoryFailPoint stellt keine Garantien für die langfristige Verfügbarkeit des Speichers während der Lebensdauer des Gates, aber Anrufer sollten immer die Dispose Methode verwenden, um sicherzustellen, dass Ressourcen MemoryFailPoint freigegeben werden.

Um ein Speichergater zu verwenden, müssen Sie ein MemoryFailPoint Objekt erstellen und die Anzahl der Megabytes (MB) des Arbeitsspeichers angeben, den der nächste Vorgang verwenden soll. Wenn nicht genügend Arbeitsspeicher verfügbar ist, wird eine InsufficientMemoryException Ausnahme ausgelöst.

Der Parameter des Konstruktors muss eine positive ganze Zahl sein. Ein negativer Wert oder 0 löst eine ArgumentOutOfRangeException Ausnahme aus.

MemoryFailPoint arbeitet mit einer Granularität von 16 MB. Alle Werte, die kleiner als 16 MB sind, werden als 16 MB behandelt, und andere Werte werden als das nächste größte Vielfache von 16 MB behandelt.

Konstruktoren

Name Beschreibung
MemoryFailPoint(Int32)

Initialisiert eine neue Instanz der MemoryFailPoint Klasse, die den für die erfolgreiche Ausführung erforderlichen Arbeitsspeicher angibt.

Methoden

Name Beschreibung
Dispose()

Veröffentlicht alle ressourcen, die von der MemoryFailPoint.

Equals(Object)

Bestimmt, ob das angegebene Objekt gleich dem aktuellen Objekt ist.

(Geerbt von Object)
Finalize()

Stellt sicher, dass Ressourcen freigegeben werden und andere Bereinigungsvorgänge ausgeführt werden, wenn der Garbage Collector das MemoryFailPoint Objekt zurückgibt.

GetHashCode()

Dient als Standardhashfunktion.

(Geerbt von Object)
GetType()

Ruft die Type der aktuellen Instanz ab.

(Geerbt von Object)
MemberwiseClone()

Erstellt eine flache Kopie der aktuellen Object.

(Geerbt von Object)
ToString()

Gibt eine Zeichenfolge zurück, die das aktuelle Objekt darstellt.

(Geerbt von Object)

Gilt für: