OutOfMemoryException Sınıf
Tanım
Önemli
Bazı bilgiler ürünün ön sürümüyle ilgilidir ve sürüm öncesinde önemli değişiklikler yapılmış olabilir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.
Bir programın yürütülmesine devam etmek için yeterli bellek olmadığında oluşan özel durum.
public ref class OutOfMemoryException : Exception
public ref class OutOfMemoryException : SystemException
public class OutOfMemoryException : Exception
public class OutOfMemoryException : SystemException
[System.Serializable]
public class OutOfMemoryException : SystemException
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class OutOfMemoryException : SystemException
type OutOfMemoryException = class
inherit Exception
type OutOfMemoryException = class
inherit SystemException
[<System.Serializable>]
type OutOfMemoryException = class
inherit SystemException
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type OutOfMemoryException = class
inherit SystemException
Public Class OutOfMemoryException
Inherits Exception
Public Class OutOfMemoryException
Inherits SystemException
- Devralma
- Devralma
- Türetilmiş
- Öznitelikler
Açıklamalar
OutOfMemoryException , 0x8007000E değerine sahip HRESULT COR_E_OUTOFMEMORYkullanır.
OutOfMemoryExceptionörneğinin ilk özellik değerlerinin listesi için bkz. OutOfMemoryException oluşturucuları.
Uyarı
Devralınan Data özelliğin değeri her zaman nullşeklindedir.
Bir OutOfMemoryException özel durumun iki önemli 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
catchgerekir.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...open System try // Outer block to handle any unexpected exceptions. try let s = "This" let s = s.Insert(2, "is ") // Throw an OutOfMemoryException exception. raise (OutOfMemoryException()) with | :? ArgumentException -> printfn "ArgumentException in String.Insert" // Execute program logic. with :? OutOfMemoryException as e -> printfn "Terminating application unexpectedly..." Environment.FailFast $"Out of Memory: {e.Message}" // The example displays the following output: // Terminating application unexpectedly...Module Example Public Sub Main() Try ' Outer block to handle any unexpected exceptions. Try Dim s As String = "This" s = s.Insert(2, "is ") ' Throw an OutOfMemoryException exception. Throw New OutOfMemoryException() Catch e As ArgumentException Console.WriteLine("ArgumentException in String.Insert") End Try ' Execute program logic. Catch e As OutOfMemoryException Console.WriteLine("Terminating application unexpectedly...") Environment.FailFast(String.Format("Out of Memory: {0}", e.Message)) End Try End Sub End Module ' 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 nesnenin StringBuilder 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öntemine yapılan çağrının oluşturduğu özel durumu gösterir.
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.
open System
open System.Text
let sb = StringBuilder(15, 15)
sb.Append "Substring #1 "
|> ignore
try
sb.Insert(0, "Substring #2 ", 1)
|> ignore
with :? OutOfMemoryException as e ->
printfn $"Out of Memory: {e.Message}"
// The example displays the following output:
// Out of Memory: Insufficient memory to continue the execution of the program.
Imports System.Text
Module Example
Public Sub Main()
Dim sb As New StringBuilder(15, 15)
sb.Append("Substring #1 ")
Try
sb.Insert(0, "Substring #2 ", 1)
Catch e As OutOfMemoryException
Console.WriteLine("Out of Memory: {0}", e.Message)
End Try
End Sub
End Module
' 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:
Oluşturucuya yapılan çağrıyı StringBuilder.StringBuilder(Int32, Int32) başka StringBuilder bir oluşturucu aşırı yükleme çağrısıyla değiştirin. Nesnenizin StringBuilder maksimum kapasitesi varsayılan değerine (olan Int32.MaxValue) ayarlanır.
Nesnedeki StringBuilder.StringBuilder(Int32, Int32) genişletmeleri barındıracak kadar büyük bir
maxCapacitydeğere sahip oluşturucuyu çağırın StringBuilder .
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
Atık 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, bellek eşlenen dosyalar, kanallar, kayıt defteri anahtarları ve bekleme tutamaçları dahil) 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ı gibi yönetilmeyen kaynaklara ayrılan belleği 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ümeleriyle (diziler, koleksiyonlar veya veritabanı veri kümeleri gibi) ç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, özel durum OutOfMemoryException sonuçlanır.
Özel durumları önlemek OutOfMemoryException için, daha az verinin bellekte yer alması veya verilerin daha küçük bellek ayırması gerektiren kesimlere bölünmesi için uygulamanızı değiştirmeniz gerekir. Örneğin:
Bir veritabanından tüm verileri alıyor ve ardından sunucuya yapılan yolculukları 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 alt kümelerdeki verileri ç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. Örnekteki çıkış, örneğin ortalamayı hesaplamadan önce dizinin tamamını bellekte depoladığı için bir OutOfMemoryException atıldığını gösterir.
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.
open System
let getData () =
let rnd = Random()
[| for i = 1 to 200000000 do
rnd.NextDouble()
if i % 10000000 = 0 then
printfn $"Retrieved {i:N0} items of data." |]
let getMean values =
let sum = Array.sum values
sum / float values.Length
let values = getData ()
// Compute mean.
printfn $"Sample mean: {getMean values}, N = {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.
Imports System.Collections.Generic
Module Example
Public Sub Main()
Dim values() As Double = GetData()
' Compute mean.
Console.WriteLine("Sample mean: {0}, N = {1}",
GetMean(values), values.Length)
End Sub
Private Function GetData() As Double()
Dim rnd As New Random()
Dim values As New List(Of Double)()
For ctr As Integer = 1 To 200000000
values.Add(rnd.NextDouble)
If ctr Mod 10000000 = 0 Then
Console.WriteLine("Retrieved {0:N0} items of data.",
ctr)
End If
Next
Return values.ToArray()
End Function
Private Function GetMean(values() As Double) As Double
Dim sum As Double = 0
For Each value In values
sum += value
Next
Return sum / values.Length
End Function
End Module
' 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, gelen verileri tüm veri kümesini bellekte depolamadan işleyerek, daha fazla işlemeye izin vermek için gerekirse verileri bir dosyaya seri hale getirerek (bu örnekte bu satırlar açıklama satırı yapılır, çünkü bu örnekte boyutu 1 GB'tan büyük bir dosya oluşturur) ve hesaplanan ortalamayı ve servis talebi sayısını çağırma yordamına döndürerek özel durumu ortadan kaldırır OutOfMemoryException .
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
open System
// open System.IO
let getResult () =
let chunkSize = 50000000
let nToGet = 200000000
let rnd = Random()
// use fs = new FileStream(@".\data.bin", FileMode.Create)
// use bin = new BinaryWriter(fs)
// bin.Write 0
let mutable n = 0
let mutable sum = 0.
for _ = 0 to int (ceil (nToGet / chunkSize |> float) - 1.) do
for _ = 0 to min (nToGet - n - 1) (chunkSize - 1) do
let value = rnd.NextDouble()
sum <- sum + value
n <- n + 1
// bin.Write(value)
// bin.Seek(0, SeekOrigin.Begin) |> ignore
// bin.Write n
sum / float n, n
let mean, n = getResult ()
printfn $"Sample mean: {mean}, N = {n:N0}"
// The example displays output like the following:
// Sample mean: 0.500022771458399, N = 200,000,000
Imports System.IO
Module Example
Public Sub Main()
Dim result As Tuple(Of Double, Long) = GetResult()
Console.WriteLine("Sample mean: {0}, N = {1:N0}",
result.Item1, result.Item2)
End Sub
Private Function GetResult As Tuple(Of Double, Long)
Dim chunkSize As Integer = 50000000
Dim nToGet As Integer = 200000000
Dim rnd As New Random()
' Dim fs As New FileStream(".\data.bin", FileMode.Create)
' Dim bin As New BinaryWriter(fs)
' bin.Write(CInt(0))
Dim n As Integer
Dim sum As Double
For outer As Integer = 0 To CInt(Math.Ceiling(nToGet/chunkSize) - 1)
For inner = 0 To Math.Min(nToGet - n - 1, chunkSize - 1)
Dim value As Double = rnd.NextDouble()
sum += value
n += 1
' bin.Write(value)
Next
Next
' bin.Seek(0, SeekOrigin.Begin)
' bin.Write(n)
' bin.Close()
Return New Tuple(Of Double, Long)(sum/n, n)
End Function
End Module
' The example displays output like the following:
' Sample mean: 0.500022771458399, N = 200,000,000
Büyük dizeleri sürekli 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 büyük olasılıkla 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 nesnenin sabit edilmesi, 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# içindeki deyimini fixed kullanarak veya yöntemini tanıtıcı türüyle GCHandleType.PinnedçağırarakGCHandle.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
| Name | Description |
|---|---|
| OutOfMemoryException() |
OutOfMemoryException sınıfının yeni bir örneğini başlatır. |
| OutOfMemoryException(SerializationInfo, StreamingContext) |
Geçersiz.
Serileştirilmiş verilerle sınıfının yeni bir örneğini OutOfMemoryException başlatır. |
| OutOfMemoryException(String, Exception) |
Sınıfın OutOfMemoryException yeni bir örneğini belirtilen bir hata iletisiyle ve bu özel durumun nedeni olan iç özel duruma başvuruyla başlatır. |
| OutOfMemoryException(String) |
Belirtilen bir hata iletisiyle sınıfının yeni bir örneğini OutOfMemoryException başlatır. |
Özellikler
| Name | Description |
|---|---|
| Data |
Özel durum hakkında kullanıcı tanımlı ek bilgiler sağlayan anahtar/değer çiftleri koleksiyonunu 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 |
Exception Geçerli özel duruma 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
| Name | Description |
|---|---|
| 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 Objectbasit 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
| Name | Description |
|---|---|
| SerializeObjectState |
Geçersiz.
Özel durum hakkında serileştirilmiş veriler içeren bir özel durum durumu nesnesi oluşturmak için bir özel durum seri hale getirildiğinde gerçekleşir. (Devralındığı yer: Exception) |