İngilizce dilinde oku

Aracılığıyla paylaş


OutOfMemoryException Sınıf

Tanım

Bir programın yürütülmesine devam etmek için yeterli bellek olmadığında oluşan özel durum.

C#
public class OutOfMemoryException : Exception
C#
public class OutOfMemoryException : SystemException
C#
[System.Serializable]
public class OutOfMemoryException : SystemException
C#
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class OutOfMemoryException : SystemException
Devralma
OutOfMemoryException
Devralma
OutOfMemoryException
Türetilmiş
Öznitelikler

Açıklamalar

OutOfMemoryException değeri 0x8007000E olan HRESULT COR_E_OUTOFMEMORYkullanır.

örneğinin ilk özellik değerlerinin OutOfMemoryExceptionlistesi için oluşturuculara OutOfMemoryException bakın.

Not

Devralınan Data özelliğin değeri her zaman nullşeklindedir.

Bir OutOfMemoryException özel durumun iki ana nedeni vardır:

  • Bir StringBuilder nesneyi özelliği tarafından StringBuilder.MaxCapacity tanımlanan uzunluktan daha fazla genişletmeye çalışıyorsunuz.

  • Ortak dil çalışma zamanı, bir işlemi başarıyla gerçekleştirmek için yeterli bitişik bellek ayıramaz. Bu özel durum, bellek ayırma gerektiren herhangi bir özellik ataması veya yöntem çağrısı tarafından oluşturulabilir. Özel durumun nedeni OutOfMemoryException hakkında daha fazla bilgi için "Yetersiz Bellek" Fiziksel Belleğe Başvurmuyor blog gönderisine bakın.

    Bu tür OutOfMemoryException bir özel durum, yıkıcı bir hatayı temsil eder. Özel durumu işlemeyi seçerseniz, aşağıdaki örnekte olduğu gibi uygulamanızı sonlandırmak ve sistem olay günlüğüne bir giriş eklemek için yöntemini çağıran Environment.FailFast bir blok eklemeniz catch gerekir.

    C#
    using System;
    
    public class Example
    {
       public static void Main()
       {
          try {
             // Outer block to handle any unexpected exceptions.
             try {
                string s = "This";
                s = s.Insert(2, "is ");
    
                // Throw an OutOfMemoryException exception.
                throw new OutOfMemoryException();
             }
             catch (ArgumentException) {
                Console.WriteLine("ArgumentException in String.Insert");
             }
    
             // Execute program logic.
          }
          catch (OutOfMemoryException e) {
             Console.WriteLine("Terminating application unexpectedly...");
             Environment.FailFast(String.Format("Out of Memory: {0}",
                                                e.Message));
          }
       }
    }
    // The example displays the following output:
    //        Terminating application unexpectedly...
    

Özel durumun oluşturulduğu koşullardan bazıları ve bunu ortadan kaldırmak için gerçekleştirebileceğiniz eylemler şunlardır:

yöntemini çağırıyorsunuz StringBuilder.Insert .

Bir StringBuilder nesnenin uzunluğunu özelliği tarafından StringBuilder.MaxCapacity belirtilen boyutun ötesinde artırmaya çalışıyorsunuz. Aşağıdaki örnek, nesnenin Length özelliğinin OutOfMemoryException maksimum kapasitesini aşmasına StringBuilder.Insert(Int32, String, Int32) neden olacak bir dize eklemeye çalıştığında yöntemi çağrısı tarafından oluşan özel durumu gösterir.

C#
using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      StringBuilder sb = new StringBuilder(15, 15);
      sb.Append("Substring #1 ");
      try {
         sb.Insert(0, "Substring #2 ", 1);
      }
      catch (OutOfMemoryException e) {
         Console.WriteLine("Out of Memory: {0}", e.Message);
      }
   }
}
// The example displays the following output:
//    Out of Memory: Insufficient memory to continue the execution of the program.

Hatayı gidermek için aşağıdakilerden birini yapabilirsiniz:

Uygulamanız 32 bit işlem olarak çalışır.

32 bit işlemler, 32 bit sistemlerde en fazla 2 GB sanal kullanıcı modu belleği ve 64 bit sistemlerde 4 GB sanal kullanıcı modu belleği ayırabilir. Bu, büyük bir ayırma gerektiğinde ortak dil çalışma zamanının yeterli bitişik bellek ayırmasını zorlaştırabilir. Buna karşılık, 64 bit işlemler 8 TB'a kadar sanal bellek ayırabilir. Bu özel durumu gidermek için uygulamanızı 64 bitlik bir platformu hedef olacak şekilde yeniden derlenin. Visual Studio'da belirli platformları hedefleme hakkında bilgi için bkz . Nasıl yapılır: Projeleri Hedef Platformlara Yapılandırma.

Uygulamanız yönetilmeyen kaynakları sızdırıyor

Çöp toplayıcı yönetilen türlere ayrılan belleği boşaltabilse de, işletim sistemi tanıtıcıları (dosyalara yönelik tanıtıcılar, belleğe eşlenen dosyalar, kanallar, kayıt defteri anahtarları ve bekleme tanıtıcıları dahil) gibi yönetilmeyen kaynaklara ayrılan belleği ve doğrudan Windows API çağrıları veya gibi mallocbellek ayırma işlevlerine yapılan çağrılar tarafından ayrılan bellek bloklarını yönetmez. Yönetilmeyen kaynakları kullanan türler arabirimini IDisposable uygular.

Yönetilmeyen kaynakları kullanan bir tür kullanıyorsanız, kullanmayı bitirdiğinizde yöntemini çağırdığınızdan IDisposable.Dispose emin olmalısınız. (Bazı türler, işlevde bir Close yöntemle aynı olan bir Dispose yöntemi de uygular.) Daha fazla bilgi için IDisposable Uygulayan Nesneleri Kullanma konusuna bakın.

Yönetilmeyen kaynakları kullanan bir tür oluşturduysanız Dispose desenini uyguladığınıza ve gerekirse bir sonlandırıcı sağladığınıza emin olun. Daha fazla bilgi için bkz . Dispose yöntemini uygulama ve Object.Finalize.

64 bitlik bir işlemde büyük bir dizi oluşturmaya çalışıyorsunuz

Varsayılan olarak, .NET Framework'teki ortak dil çalışma zamanı boyutu 2 GB'ı aşan tek nesnelere izin vermez. Bu varsayılanı geçersiz kılmak için gcAllowVeryLargeObjects> yapılandırma dosyası ayarını kullanarak< toplam boyutu 2 GB'ı aşan dizileri etkinleştirebilirsiniz. .NET Core'da, 2 GB'tan büyük diziler için destek varsayılan olarak etkindir.

Bellekte çok büyük veri kümeleri (diziler, koleksiyonlar veya veritabanı veri kümeleri gibi) ile çalışıyorsunuz.

Bellekte bulunan veri yapıları veya veri kümeleri, ortak dil çalışma zamanının bunlar için yeterli bitişik bellek ayıramayacağı kadar büyük hale geldiğinde, bir OutOfMemoryException özel durum sonucu verir.

Özel durumları önlemek OutOfMemoryException için, uygulamanızı daha az verinin bellekte yer alması veya verilerin daha küçük bellek ayırmaları gerektiren segmentlere bölünmesi için değiştirmeniz gerekir. Örnek:

  • Bir veritabanından tüm verileri alıyor ve ardından sunucuya gidişleri en aza indirmek için uygulamanızda filtrelediyseniz, sorgularınızı yalnızca uygulamanızın ihtiyaç duyduğu veri alt kümesini döndürecek şekilde değiştirmeniz gerekir. Büyük tablolarla çalışırken, birden çok sorgu neredeyse her zaman tek bir tablodaki tüm verileri alıp düzenlemekten daha verimlidir.

  • Kullanıcıların dinamik olarak oluşturduğu sorguları yürütüyorsanız, sorgu tarafından döndürülen kayıt sayısının sınırlı olduğundan emin olmanız gerekir.

  • Boyutu özel durumla OutOfMemoryException sonuçlanan büyük diziler veya diğer koleksiyon nesneleri kullanıyorsanız, uygulamanızı tek seferde çalışmak yerine verileri alt kümelerde çalışacak şekilde değiştirmeniz gerekir.

Aşağıdaki örnek, 200 milyon kayan nokta değerinden oluşan bir dizi alır ve sonra bunların ortalamasını hesaplar. Örnekten elde ettiği çıkış, örneğin ortalamayı hesaplamadan önce dizinin tamamını bellekte depoladığından bir OutOfMemoryException oluşturulur.

C#
using System;
using System.Collections.Generic;

public class Example
{
   public static void Main()
   {
      Double[] values = GetData();
      // Compute mean.
      Console.WriteLine("Sample mean: {0}, N = {1}",
                        GetMean(values), values.Length);
   }

   private static Double[] GetData()
   {
      Random rnd = new Random();
      List<Double> values = new List<Double>();
      for (int ctr = 1; ctr <= 200000000; ctr++) {
         values.Add(rnd.NextDouble());
         if (ctr % 10000000 == 0)
            Console.WriteLine("Retrieved {0:N0} items of data.",
                              ctr);
      }
      return values.ToArray();
   }

   private static Double GetMean(Double[] values)
   {
      Double sum = 0;
      foreach (var value in values)
         sum += value;

      return sum / values.Length;
   }
}
// The example displays output like the following:
//    Retrieved 10,000,000 items of data.
//    Retrieved 20,000,000 items of data.
//    Retrieved 30,000,000 items of data.
//    Retrieved 40,000,000 items of data.
//    Retrieved 50,000,000 items of data.
//    Retrieved 60,000,000 items of data.
//    Retrieved 70,000,000 items of data.
//    Retrieved 80,000,000 items of data.
//    Retrieved 90,000,000 items of data.
//    Retrieved 100,000,000 items of data.
//    Retrieved 110,000,000 items of data.
//    Retrieved 120,000,000 items of data.
//    Retrieved 130,000,000 items of data.
//
//    Unhandled Exception: OutOfMemoryException.

Aşağıdaki örnek, veri kümesinin tamamını bellekte depolamadan gelen verileri işleyerek, daha fazla işlemeye izin vermek için gerekirse verileri bir dosyaya seri hale getirerek (bu örnekte boyutu 1 GB'tan büyük bir dosya oluşturduğundan bu satırlar açıklama satırı yapılır) ve hesaplanan ortalamayı ve servis talebi sayısını çağırma yordamına döndürerek özel durumu ortadan kaldırır OutOfMemoryException .

C#
using System;
using System.IO;

public class Example
{
   public static void Main()
   {
      Tuple<Double, long> result = GetResult();
      Console.WriteLine("Sample mean: {0}, N = {1:N0}",
                        result.Item1, result.Item2);
   }

   private static Tuple<Double, long> GetResult()
   {
      int chunkSize = 50000000;
      int nToGet = 200000000;
      Random rnd = new Random();
      // FileStream fs = new FileStream(@".\data.bin", FileMode.Create);
      // BinaryWriter bin = new BinaryWriter(fs);
      // bin.Write((int)0);
      int n = 0;
      Double sum = 0;
      for (int outer = 0;
           outer <= ((int) Math.Ceiling(nToGet * 1.0 / chunkSize) - 1);
           outer++) {
         for (int inner = 0;
              inner <= Math.Min(nToGet - n - 1, chunkSize - 1);
              inner++) {
            Double value = rnd.NextDouble();
            sum += value;
            n++;
            // bin.Write(value);
         }
      }
      // bin.Seek(0, SeekOrigin.Begin);
      // bin.Write(n);
      // bin.Close();
      return new Tuple<Double, long>(sum/n, n);
   }
}
// The example displays output like the following:
//    Sample mean: 0.500022771458399, N = 200,000,000

Büyük dizeleri art arda birleştirirsiniz.

Dizeler sabit olduğundan, her dize birleştirme işlemi yeni bir dize oluşturur. Küçük dizelerin veya az sayıda birleştirme işleminin etkisi göz ardı edilebilir. Ancak büyük dizeler veya çok fazla sayıda birleştirme işlemi için dize birleştirme çok sayıda bellek ayırmasına ve bellek parçalanmasına, düşük performansa ve muhtemelen OutOfMemoryException özel durumlara yol açabilir.

Büyük dizeleri birleştirirken veya çok sayıda birleştirme işlemi gerçekleştirirken, sınıfı yerine sınıfını String kullanmanız StringBuilder gerekir. Dizeyi düzenlemeyi bitirdiğinizde, yöntemini çağırarak örneği bir dizeye dönüştürün StringBuilderStringBuilder.ToString .

Belleğe çok sayıda nesne sabitlersiniz.

Bellekte uzun süreler boyunca çok sayıda nesne sabitlemek, atık toplayıcının bitişik bellek bloklarını ayırmasını zorlaştırabilir. Belleğe çok sayıda nesne sabitlediyseniz, örneğin C# dilinde deyimini fixed kullanarak veya yöntemini tanıtıcı türüyle GCHandleType.Pinnedçağırarak GCHandle.Alloc(Object, GCHandleType) özel durumu ele OutOfMemoryException almak için aşağıdakileri yapabilirsiniz.

  • Her nesnenin gerçekten sabitlenmesi gerekip gerekmediğini değerlendirin,

  • Her nesnenin mümkün olan en kısa sürede kaldırıldığından emin olun.

  • Belleği sabitlemek için yöntemine yapılan her çağrının GCHandle.Alloc(Object, GCHandleType) , bu belleği kaldırmak için yöntemine GCHandle.Free karşılık gelen bir çağrısı olduğundan emin olun.

Aşağıdaki Microsoft ara (MSIL) yönergeleri bir OutOfMemoryException özel durum oluşturur:

Oluşturucular

OutOfMemoryException()

OutOfMemoryException sınıfının yeni bir örneğini başlatır.

OutOfMemoryException(SerializationInfo, StreamingContext)
Geçersiz.

OutOfMemoryException sınıfının yeni bir örneğini serileştirilmiş verilerle başlatır.

OutOfMemoryException(String)

Belirtilen hata iletisiyle sınıfının yeni bir örneğini OutOfMemoryException başlatır.

OutOfMemoryException(String, Exception)

Belirtilen bir hata iletisi ve bu özel durumun nedeni olan iç özel duruma başvuru ile sınıfının yeni bir örneğini OutOfMemoryException başlatır.

Özellikler

Data

Özel durum hakkında kullanıcı tanımlı ek bilgiler sağlayan bir anahtar/değer çifti koleksiyonu alır.

(Devralındığı yer: Exception)
HelpLink

Bu özel durumla ilişkili yardım dosyasının bağlantısını alır veya ayarlar.

(Devralındığı yer: Exception)
HResult

Belirli bir özel duruma atanan kodlanmış sayısal bir değer olan HRESULT değerini alır veya ayarlar.

(Devralındığı yer: Exception)
InnerException

Geçerli özel duruma Exception neden olan örneği alır.

(Devralındığı yer: Exception)
Message

Geçerli özel durumu açıklayan bir ileti alır.

(Devralındığı yer: Exception)
Source

Hataya neden olan uygulamanın veya nesnenin adını alır veya ayarlar.

(Devralındığı yer: Exception)
StackTrace

Çağrı yığınındaki anlık çerçevelerin dize gösterimini alır.

(Devralındığı yer: Exception)
TargetSite

Geçerli özel durumu oluşturan yöntemini alır.

(Devralındığı yer: Exception)

Yöntemler

Equals(Object)

Belirtilen nesnenin geçerli nesneye eşit olup olmadığını belirler.

(Devralındığı yer: Object)
GetBaseException()

Türetilmiş bir sınıfta geçersiz kılındığında, sonraki bir veya daha fazla özel durumun kök nedeni olan değerini döndürür Exception .

(Devralındığı yer: Exception)
GetHashCode()

Varsayılan karma işlevi işlevi görür.

(Devralındığı yer: Object)
GetObjectData(SerializationInfo, StreamingContext)
Geçersiz.

Türetilmiş bir sınıfta geçersiz kılındığında, özel durum hakkındaki bilgilerle öğesini ayarlar SerializationInfo .

(Devralındığı yer: Exception)
GetType()

Geçerli örneğin çalışma zamanı türünü alır.

(Devralındığı yer: Exception)
MemberwiseClone()

Geçerli Objectöğesinin sığ bir kopyasını oluşturur.

(Devralındığı yer: Object)
ToString()

Geçerli özel durumun dize gösterimini oluşturur ve döndürür.

(Devralındığı yer: Exception)

Ekinlikler

SerializeObjectState
Geçersiz.

Bir özel durum, özel durum hakkında serileştirilmiş veriler içeren bir özel durum nesnesi oluşturmak üzere seri hale getirildiğinde gerçekleşir.

(Devralındığı yer: Exception)

Şunlara uygulanır

Ürün Sürümler
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

Ayrıca bkz.