다음을 통해 공유


MemoryFailPoint 클래스

정의

작업을 실행하기 전에 메모리 리소스가 충분한지 확인합니다. 이 클래스는 상속될 수 없습니다.

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 메모리 부족으로 인 한 손상을 방지 하려면 자체를 애플리케이션을 수 있습니다. 어휘 scope 내에서 사용해야 합니다. 다음 예제에서는 스레드를 실행하여 작업 큐의 항목을 처리합니다. 각 스레드를 시작하기 전에 를 사용하여 MemoryFailPoint사용 가능한 메모리 리소스를 확인합니다. 예외가 throw되면 기본 메서드는 다음 스레드를 시작하기 전에 메모리를 사용할 수 있게 될 때까지 기다립니다.

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

설명

참고

이 클래스는 고급 개발에 사용하기 위한 것입니다.

클래스의 instance 만들면 MemoryFailPoint 메모리 게이트가 만들어집니다. 메모리 게이트는 많은 양의 메모리가 필요한 작업을 시작하기 전에 충분한 리소스를 확인합니다. 검사 실패하면 예외가 InsufficientMemoryException throw됩니다. 이 예외는 작업이 시작되지 않도록 하고 리소스 부족으로 인한 실패 가능성을 줄입니다. 이렇게 하면 코드의 임의 위치에서 예외를 OutOfMemoryException 부적절하게 처리하여 발생할 수 있는 예외 및 상태 손상을 방지하기 위해 성능을 저하할 수 있습니다.

중요

이 형식이 구현 하는 IDisposable 인터페이스입니다. 형식을 사용 하 여 마쳤으면 직접 또는 간접적으로의 삭제 해야 있습니다. 직접 형식의 dispose 호출 해당 Dispose 의 메서드를 try/catch 블록입니다. 삭제 하지 직접, 언어 구문 같은 사용 using (C#에서) 또는 Using (Visual Basic에서는). 자세한 내용은 "를 사용 하는 개체는 구현 IDisposable" 섹션을 참조 하세요.를 IDisposable 인터페이스 항목입니다.

예외를 InsufficientMemoryException throw하면 애플리케이션은 작업을 완료할 수 없다는 예상과 애플리케이션 상태가 손상되었을 수 있는 부분적으로 완료된 작업을 구분할 수 있습니다. 이렇게 하면 현재 언로드 필요할 수 있는 비관적 에스컬레이션 정책의 빈도를 줄이려면 애플리케이션 AppDomain 프로세스를 재생 합니다.

MemoryFailPoint 는 모든 가비지 수집 힙에서 충분한 메모리 및 연속 가상 주소 공간을 사용할 수 있는지 확인하고 스왑 파일의 크기를 늘릴 수 있는지 확인합니다. MemoryFailPoint 는 게이트 수명 동안 메모리의 장기 가용성을 보장하지 않지만 호출자는 항상 메서드를 사용하여 Dispose 연결된 MemoryFailPoint 리소스가 해제되도록 해야 합니다.

메모리 게이트를 사용하려면 개체를 MemoryFailPoint 만들고 다음 작업에서 사용할 것으로 예상되는 메모리의 MB(메가바이트) 수를 지정해야 합니다. 충분한 메모리를 사용할 수 없는 경우 예외가 InsufficientMemoryException throw됩니다.

생성자의 매개 변수는 양의 정수여야 합니다. 음수 값 또는 0이면 예외가 ArgumentOutOfRangeException 발생합니다.

MemoryFailPoint 는 16MB의 세분성으로 작동합니다. 16MB보다 작은 값은 16MB로 처리되고 다른 값은 16MB의 다음으로 큰 배수로 처리됩니다.

생성자

MemoryFailPoint(Int32)

성공적으로 실행하는 데 필요한 메모리 양을 지정하여 MemoryFailPoint 클래스의 새 인스턴스를 초기화합니다.

메서드

Dispose()

MemoryFailPoint에서 사용하는 모든 리소스를 해제합니다.

Equals(Object)

지정된 개체가 현재 개체와 같은지 확인합니다.

(다음에서 상속됨 Object)
Finalize()

가비지 컬렉션기에서 MemoryFailPoint 개체를 회수할 때 리소스가 해제되고 다른 정리 작업이 수행되도록 합니다.

GetHashCode()

기본 해시 함수로 작동합니다.

(다음에서 상속됨 Object)
GetType()

현재 인스턴스의 Type을 가져옵니다.

(다음에서 상속됨 Object)
MemberwiseClone()

현재 Object의 단순 복사본을 만듭니다.

(다음에서 상속됨 Object)
ToString()

현재 개체를 나타내는 문자열을 반환합니다.

(다음에서 상속됨 Object)

적용 대상