Bagikan melalui


MemoryFailPoint Kelas

Definisi

Memeriksa sumber daya memori yang memadai sebelum menjalankan operasi. Kelas ini tidak dapat diwariskan.

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
Warisan
Penerapan

Contoh

MemoryFailPoint memungkinkan aplikasi untuk memperlambat dirinya sendiri untuk menghindari kehabisan memori dengan cara yang rusak. Ini harus digunakan dalam cakupan leksikal. Contoh berikut meluncurkan utas untuk memproses item dalam antrean kerja. Sebelum setiap utas diluncurkan, sumber daya memori yang tersedia diperiksa menggunakan MemoryFailPoint. Jika pengecualian dilemparkan, metode utama menunggu sampai memori tersedia sebelum meluncurkan utas berikutnya.

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

Keterangan

Catatan

Kelas ini ditujukan untuk digunakan dalam pengembangan lanjutan.

Membuat instans MemoryFailPoint kelas membuat gerbang memori. Gerbang memori memeriksa sumber daya yang memadai sebelum memulai aktivitas yang membutuhkan memori dalam jumlah besar. Gagal memeriksa hasil dalam pengecualian yang InsufficientMemoryException dilemparkan. Pengecualian ini mencegah operasi dimulai dan mengurangi kemungkinan kegagalan karena kurangnya sumber daya. Ini memungkinkan Anda mengurangi performa untuk menghindari OutOfMemoryException pengecualian dan kerusakan status apa pun yang dapat diakibatkan oleh penanganan pengecualian yang tidak tepat di lokasi arbitrer dalam kode Anda.

Penting

Jenis ini mengimplementasikan IDisposable antarmuka. Ketika Anda telah selesai menggunakan jenis , Anda harus membuangnya baik secara langsung atau tidak langsung. Untuk membuang jenis secara langsung, panggil metodenya Dispose dalam try/catch blok. Untuk membuangnya secara tidak langsung, gunakan konstruksi bahasa seperti using (di C#) atau Using (di Visual Basic). Untuk informasi selengkapnya, lihat bagian "Menggunakan Objek yang Mengimplementasikan IDisposable" di IDisposable topik antarmuka.

Dengan melemparkan InsufficientMemoryException pengecualian, aplikasi dapat membedakan antara perkiraan bahwa operasi tidak akan dapat diselesaikan dan operasi yang sebagian selesai yang mungkin telah merusak status aplikasi. Ini memungkinkan aplikasi untuk mengurangi frekuensi kebijakan eskalasi pesimis, yang mungkin memerlukan pembongkaran saat ini AppDomain atau mendaur ulang proses.

MemoryFailPoint memeriksa untuk melihat apakah memori yang cukup dan ruang alamat virtual berturut-turut tersedia di semua tumpukan pengumpulan sampah, dan dapat meningkatkan ukuran file pertukaran. MemoryFailPoint tidak memberikan jaminan mengenai ketersediaan memori jangka panjang selama masa pakai gerbang, tetapi pemanggil harus selalu menggunakan Dispose metode untuk memastikan bahwa sumber daya yang terkait dirilis MemoryFailPoint .

Untuk menggunakan gerbang memori, Anda harus membuat MemoryFailPoint objek dan menentukan jumlah megabyte (MB) memori yang diharapkan digunakan operasi berikutnya. Jika memori yang cukup tidak tersedia, InsufficientMemoryException pengecualian akan dilemparkan.

Parameter konstruktor harus berupa bilangan bulat positif. Nilai negatif atau 0 menimbulkan ArgumentOutOfRangeException pengecualian.

MemoryFailPoint beroperasi pada granularitas 16 MB. Nilai apa pun yang lebih kecil dari 16 MB diperlakukan sebagai 16 MB, dan nilai lainnya diperlakukan sebagai kelipatan terbesar berikutnya sebesar 16 MB.

Konstruktor

MemoryFailPoint(Int32)

Menginisialisasi instans MemoryFailPoint baru kelas, menentukan jumlah memori yang diperlukan untuk keberhasilan eksekusi.

Metode

Dispose()

Merilis semua sumber daya yang MemoryFailPointdigunakan oleh .

Equals(Object)

Menentukan apakah objek yang ditentukan sama dengan objek saat ini.

(Diperoleh dari Object)
Finalize()

Memastikan bahwa sumber daya dibebaskan dan operasi pembersihan lainnya dilakukan ketika pengumpul sampah merebut MemoryFailPoint kembali objek.

GetHashCode()

Berfungsi sebagai fungsi hash default.

(Diperoleh dari Object)
GetType()

Mendapatkan dari instans Type saat ini.

(Diperoleh dari Object)
MemberwiseClone()

Membuat salinan dangkal dari saat ini Object.

(Diperoleh dari Object)
ToString()

Mengembalikan string yang mewakili objek saat ini.

(Diperoleh dari Object)

Berlaku untuk