MemoryFailPoint 類別

定義

在執行作業前檢查記憶體資源是否足夠。Checks for sufficient memory resources before executing an operation. 這個類別無法被繼承。This class cannot be inherited.

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
繼承
實作

範例

MemoryFailPoint讓應用程式減緩自己的速度, 以避免損毀的記憶體用盡。MemoryFailPoint enables an application to slow itself to avoid running out of memory in a corrupting manner. 它應該在詞法範圍內使用。It should be used within a lexical scope. 下列範例會啟動執行緒, 以處理工作佇列中的專案。The following example launches threads to process items in a work queue. 在啟動每個執行緒之前, 會使用MemoryFailPoint來檢查可用的記憶體資源。Before each thread is launched, the available memory resources are checked using MemoryFailPoint. 如果擲回例外狀況, main 方法會等到記憶體可用, 然後才啟動下一個執行緒。If an exception is thrown, the main method waits until memory is available before launching the next 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);

    }
}

備註

注意

這個類別的用途是要在 advanced 開發中使用。This class is intended for use in advanced development.

建立MemoryFailPoint類別的實例會建立記憶體閘道。Creating an instance of the MemoryFailPoint class creates a memory gate. 記憶體閘道會在起始需要海量儲存體的活動之前, 先檢查是否有足夠的資源。A memory gate checks for sufficient resources before initiating an activity that requires a large amount of memory. 若失敗, 則會導致InsufficientMemoryException擲回例外狀況。Failing the check results in an InsufficientMemoryException exception being thrown. 此例外狀況會阻止作業啟動, 並降低因資源不足而失敗的可能性。This exception prevents an operation from being started and reduces the possibility of failure due to lack of resources. 這可讓您降低效能, 以OutOfMemoryException避免例外狀況和任何狀態損毀, 這可能是因為程式碼中的任意位置不適當地處理例外狀況。This enables you decrease performance to avoid an OutOfMemoryException exception and any state corruption that may result from improper handling of the exception in arbitrary locations in your code.

重要

此型別代表 IDisposable 介面。This type implements the IDisposable interface. 當您完成使用型別時,您應該直接或間接處置它。When you have finished using the type, you should dispose of it either directly or indirectly. 若要直接處置型別,請呼叫其 try/catch 區塊中的 Dispose 方法。To dispose of the type directly, call its Dispose method in a try/catch block. 若要間接處置它,請使用語言建構函式,例如 using (在 C# 中) 或 Using (在 Visual Basic 中)。To dispose of it indirectly, use a language construct such as using (in C#) or Using (in Visual Basic). 如需詳細資訊,請參閱 IDisposable 介面文章中的<使用實作 IDisposable 的物件>一節。For more information, see the "Using an Object that Implements IDisposable" section in the IDisposable interface topic.

藉由擲回例外狀況,應用程式可以區別估計作業將無法完成的作業,以及可能已損毀應用程式狀態的部分完成作業。InsufficientMemoryExceptionBy throwing an InsufficientMemoryException exception, an application can distinguish between an estimate that an operation will not be able to complete and a partially completed operation that may have corrupted the application state. 這可讓應用程式降低封閉式擴大原則的頻率, 這可能需要卸載目前AppDomain或回收進程。This allows an application to reduce the frequency of a pessimistic escalation policy, which may require unloading the current AppDomain or recycling the process.

MemoryFailPoint檢查是否有足夠的記憶體和連續的虛擬位址空間可用於所有垃圾收集堆積中, 而且可能會增加交換檔的大小。MemoryFailPoint checks to see whether sufficient memory and consecutive virtual address space are available in all garbage collection heaps, and may increase the size of the swap file. MemoryFailPoint在閘道的存留期內, 對於記憶體的長期可用性不提供保證, 但呼叫端應該一律使用Dispose方法, 以確保釋放與MemoryFailPoint關聯的資源。MemoryFailPoint makes no guarantees regarding the long-term availability of the memory during the lifetime of the gate, but callers should always use the Dispose method to ensure that resources associated with MemoryFailPoint are released.

若要使用記憶體閘道, 您必須建立MemoryFailPoint物件, 並指定下一個作業預期會使用的記憶體 (mb) 數目。To use a memory gate, you must create a MemoryFailPoint object and specify the number of megabytes (MB) of memory that the next operation is expected to use. 如果沒有足夠的記憶體可供使用InsufficientMemoryException , 則會擲回例外狀況。If enough memory is not available, an InsufficientMemoryException exception is thrown.

此函式的參數必須是正整數。The parameter of the constructor must be a positive integer. 負值會引發ArgumentOutOfRangeException例外狀況。A negative value raises an ArgumentOutOfRangeException exception.

MemoryFailPoint以 16 MB 的細微性操作。MemoryFailPoint operates at a granularity of 16 MB. 小於 16 MB 的任何值都會被視為 16 MB, 而其他值會被視為 16 MB 的下一個最大倍數。Any values smaller than 16 MB are treated as 16 MB, and other values are treated as the next largest multiple of 16 MB.

建構函式

MemoryFailPoint(Int32)

初始化 MemoryFailPoint 類別的新執行個體,並指定順利執行所需的記憶體容量。Initializes a new instance of the MemoryFailPoint class, specifying the amount of memory required for successful execution.

方法

Dispose()

釋放 MemoryFailPoint 所使用的所有資源。Releases all resources used by the MemoryFailPoint.

Equals(Object)

判斷指定的物件是否等於目前的物件。Determines whether the specified object is equal to the current object.

(繼承來源 Object)
Finalize()

確認釋出資源,並在記憶體回收行程回收 MemoryFailPoint 物件時執行其他清除作業。Ensures that resources are freed and other cleanup operations are performed when the garbage collector reclaims the MemoryFailPoint object.

GetHashCode()

做為預設雜湊函式。Serves as the default hash function.

(繼承來源 Object)
GetType()

取得目前執行個體的 TypeGets the Type of the current instance.

(繼承來源 Object)
MemberwiseClone()

建立目前 Object 的淺層複本 (Shallow Copy)。Creates a shallow copy of the current Object.

(繼承來源 Object)
ToString()

傳回代表目前物件的字串。Returns a string that represents the current object.

(繼承來源 Object)

安全性

SecurityPermission
用於呼叫非受控碼。for calling unmanaged code. 相關聯的UnmanagedCode列舉:。Associated enumeration: UnmanagedCode. 安全性動作:LinkDemandSecurity action: LinkDemand

適用於