(0) exportieren Drucken
Alle erweitern

MemoryFailPoint-Klasse

Hinweis: Diese Klasse ist neu in .NET Framework, Version 2.0.

Überprüfen Sie vor der Ausführung, ob ausreichend Arbeitsspeicher vorhanden ist. Diese Klasse kann nicht geerbt werden.

Namespace: System.Runtime
Assembly: mscorlib (in mscorlib.dll)

public sealed class MemoryFailPoint : CriticalFinalizerObject, IDisposable
public final class MemoryFailPoint extends CriticalFinalizerObject implements IDisposable
public final class MemoryFailPoint extends CriticalFinalizerObject implements IDisposable

HinweisHinweis

Diese Klasse ist für die Verwendung bei fortgeschrittener Entwicklung konzipiert.

Durch das Erstellen der Instanz einer MemoryFailPoint-Klasse wird ein Speichergate erstellt. Ein Speichergate wird dazu verwendet, zu überprüfen, ob ausreichend Ressourcen vorhanden sind, bevor eine Aktivität initiiert wird, die viel Arbeitsspeicher erfordert. Wenn die Überprüfung nicht erfolgreich ist, wird eine InsufficientMemoryException ausgelöst, die das Starten eines Vorgangs verhindert und somit die Möglichkeit verringert, dass bei einer Anwendung aufgrund von Ressourcenmangel während der Ausführung ein Fehler auftritt. Dies ermöglicht es einer Anwendung, die Leistung zu verringern, um eine OutOfMemoryException und Zustandsbeschädigungen zu vermeiden, die auf eine nicht ordnungsgemäße Behandlung einer OutOfMemoryException in beliebigen Positionen im Code zurückzuführen ist.

Durch das Auslösen einer InsufficientMemoryException kann eine Anwendung zwischen einer wiederherstellbaren Schätzung, die von einem Vorgang nicht abgeschlossen werden kann, und einer OutOfMemoryException während eines teilweise abgeschlossenen Vorgangs unterscheiden, die den Zustand beschädigen kann. Dies ermöglicht es der Anwendung, die Häufigkeit einer pessimistischen Eskalationsrichtlinie zu verringern, die das Entladen der aktuellen AppDomain oder das Recycling des Prozesses erforderlich machen kann.

MemoryFailPoint überprüft, ob in allen Garbage Collection-Heaps ausreichend Arbeitsspeicher und aufeinanderfolgende virtuelle Arbeitsbereiche verfügbar sind und kann bei Bedarf die Datei austauschen. MemoryFailPoint gewährleistet keine Langzeitverfügbarkeit des Arbeitsspeichers während der Lebensdauer des Gates. Aufrufer müssen immer Dispose aufrufen, um sicherzustellen, dass MemoryFailPoint zugeordnete Ressourcen freigegeben werden.

Zum Verwenden eines Speichergates müssen Sie ein MemoryFailPoint-Objekt erstellen, das die Megabytes des Arbeitsspeichers angibt, die bei dem Vorgang verwendet werden. Wenn nicht genug Arbeitsspeicher verfügbar ist, wird eine InsufficientMemoryException ausgelöst.

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

MemoryFailPoint ermöglicht es einer Anwendung, langsamer zu werden, um zu vermeiden, dass Arbeitsspeicher fehlt und somit Schäden entstehen. Die Verwendung muss immer in einem lexikalischen Bereich erfolgen. Im folgenden Codebeispiel werden Threads gestartet, um die Elemente in einer Arbeitswarteschlange zu verarbeiten. Vor dem Starten eines Threads werden die verfügbaren Arbeitsspeicherressourcen mithilfe von MemoryFailPoint überprüft. Wenn eine Ausnahme ausgelöst wird, wartet die Hauptmethode vor dem Starten des nächsten Threads, bis Arbeitsspeicher verfügbar ist.

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

    }
}

Alle öffentlichen statischen (Shared in Visual Basic) Member dieses Typs sind threadsicher. Bei Instanzmembern ist die Threadsicherheit nicht gewährleistet.

Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework unterstützt nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen.

.NET Framework

Unterstützt in: 2.0
Microsoft führt eine Onlineumfrage durch, um Ihre Meinung zur MSDN-Website zu erfahren. Wenn Sie sich zur Teilnahme entscheiden, wird Ihnen die Onlineumfrage angezeigt, sobald Sie die MSDN-Website verlassen.

Möchten Sie an der Umfrage teilnehmen?
Anzeigen:
© 2014 Microsoft