OutOfMemoryException Klass
Definition
Viktigt
En del information gäller för förhandsversionen av en produkt och kan komma att ändras avsevärt innan produkten blir allmänt tillgänglig. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, avseende informationen som visas här.
Undantaget som utlöses när det inte finns tillräckligt med minne för att fortsätta körningen av ett program.
public ref class OutOfMemoryException : Exception
public ref class OutOfMemoryException : SystemException
public class OutOfMemoryException : Exception
[System.Serializable]
public class OutOfMemoryException : SystemException
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class OutOfMemoryException : SystemException
public class OutOfMemoryException : SystemException
type OutOfMemoryException = class
inherit Exception
[<System.Serializable>]
type OutOfMemoryException = class
inherit SystemException
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type OutOfMemoryException = class
inherit SystemException
type OutOfMemoryException = class
inherit SystemException
Public Class OutOfMemoryException
Inherits Exception
Public Class OutOfMemoryException
Inherits SystemException
- Arv
- Arv
- Härledda
- Attribut
Kommentarer
OutOfMemoryException använder HRESULT COR_E_OUTOFMEMORY, som har värdet 0x8007000E.
För en lista över inledande egenskapsvärden för en instans av OutOfMemoryException, se i OutOfMemoryException-konstruktorn.
Note
Värdet för den ärvda Data egenskapen är alltid null.
Ett OutOfMemoryException undantag har två huvudsakliga orsaker:
Du försöker expandera ett StringBuilder objekt utöver den längd som definieras av dess StringBuilder.MaxCapacity egenskap.
Den vanliga språkkörningen kan inte allokera tillräckligt med sammanhängande minne för att utföra en åtgärd. Det här undantaget kan genereras av alla egenskapstilldelningar eller metodanrop som kräver en minnesallokering. Mer information om orsaken till undantaget finns i blogginlägget OutOfMemoryException"Slut på minne" refererar inte till fysiskt minne.
Den här typen av OutOfMemoryException undantag representerar ett oåterkalleligt fel. Om du väljer att hantera undantaget bör du inkludera ett
catchblock som anropar Environment.FailFast metoden för att avsluta appen och lägga till en post i systemhändelseloggen, som i följande exempel.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...
Några av de villkor under vilka undantaget utlöses och de åtgärder du kan vidta för att eliminera det inkluderar följande:
Du anropar StringBuilder.Insert metoden.
Du försöker öka längden på ett StringBuilder objekt utöver den storlek som anges av dess StringBuilder.MaxCapacity egenskap. I följande exempel visas undantaget OutOfMemoryException som genereras av ett anrop till StringBuilder.Insert(Int32, String, Int32) metoden när exemplet försöker infoga en sträng som skulle göra att objektets Length egenskap överskrider dess maximala kapacitet.
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.
Du kan göra något av följande för att åtgärda felet:
Ersätt anropet StringBuilder.StringBuilder(Int32, Int32) till konstruktorn med ett anrop till andra StringBuilder konstruktoröverlagringar. Objektets StringBuilder maximala kapacitet anges till dess standardvärde, som är Int32.MaxValue.
StringBuilder.StringBuilder(Int32, Int32) Anropa konstruktorn med ett
maxCapacityvärde som är tillräckligt stort för att hantera eventuella expansioner till StringBuilder objektet.
Appen körs som en 32-bitarsprocess.
32-bitarsprocesser kan allokera högst 2 GB virtuellt minne i användarläge på 32-bitarssystem och 4 GB minne i virtuellt användarläge på 64-bitarssystem. Detta kan göra det svårare för den gemensamma språkkörningen att allokera tillräckligt med sammanhängande minne när en stor allokering behövs. Däremot kan 64-bitarsprocesser allokera upp till 8 TB virtuellt minne. Åtgärda det här undantaget genom att kompilera om din app så att den riktar in sig på en 64-bitarsplattform. Information om hur du riktar in dig på specifika plattformar i Visual Studio finns i How to: Configure Projects to Target Platforms.
Appen läcker ohanterade resurser
Även om skräpinsamlaren kan frigöra minne som allokerats till hanterade typer, hanterar den inte minne som allokerats till ohanterade resurser, till exempel operativsystemreferenser (inklusive referenser till filer, minnesmappade filer, rör, registernycklar och väntehandtag) och minnesblock som allokerats direkt av Windows API-anrop eller genom anrop till minnesallokeringsfunktioner som malloc. Typer som använder ohanterade resurser implementerar IDisposable gränssnittet.
Om du använder en typ som använder ohanterade resurser bör du anropa dess IDisposable.Dispose metod när du har använt den. (Vissa typer implementerar också en Close metod som är identisk i funktionen med en Dispose metod.) Mer information finns i avsnittet Använda objekt som implementerar IDisposable .
Om du har skapat en typ som använder ohanterade resurser kontrollerar du att du har implementerat mönstret Kassera och, om det behövs, angett en finalizer. Mer information finns i Implementera en Dispose-metod och Object.Finalize.
Du försöker skapa en stor matris i en 64-bitarsprocess
Som standard tillåter inte den gemensamma språkkörningen i .NET Framework enskilda objekt vars storlek överskrider 2 GB. Om du vill åsidosätta den här standardinställningen kan du använda konfigurationsfilinställningen< gcAllowVeryLargeObjects> för att aktivera matriser vars totala storlek överstiger 2 GB. På .NET Core är stöd för matriser på större än 2 GB aktiverat som standard.
Du arbetar med mycket stora uppsättningar data (till exempel matriser, samlingar eller databasdatauppsättningar) i minnet.
När datastrukturer eller datauppsättningar som finns i minnet blir så stora att den gemensamma språkkörningen inte kan allokera tillräckligt med sammanhängande minne för dem, resulterar ett OutOfMemoryException undantag.
För att förhindra undantagen OutOfMemoryException måste du ändra programmet så att mindre data finns i minnet, eller så delas data in i segment som kräver mindre minnesallokeringar. Ett exempel:
Om du hämtar alla data från en databas och sedan filtrerar dem i din app för att minimera resor till servern bör du ändra dina frågor så att de endast returnerar den delmängd av data som din app behöver. När du arbetar med stora tabeller är flera frågor nästan alltid effektivare än att hämta alla data i en enda tabell och sedan ändra dem.
Om du kör frågor som användarna skapar dynamiskt bör du se till att antalet poster som returneras av frågan är begränsat.
Om du använder stora matriser eller andra samlingsobjekt vars storlek resulterar i ett OutOfMemoryException undantag bör du ändra programmet så att de fungerar i underuppsättningar i stället för att arbeta med allt på en gång.
I följande exempel hämtas en matris som består av 200 miljoner flyttalsvärden och sedan beräknar deras medelvärde. Utdata från exemplet visar att eftersom exemplet lagrar hela matrisen i minnet innan medelvärdet beräknas genereras en OutOfMemoryException .
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.
Följande exempel eliminerar OutOfMemoryException undantaget genom att bearbeta inkommande data utan att lagra hela datauppsättningen i minnet, serialisera data till en fil om det behövs för att tillåta ytterligare bearbetning (dessa rader kommenteras ut i exemplet, eftersom de i det här fallet producerar en fil vars storlek är större än 1 GB) och returnerar det beräknade medelvärdet och antalet fall till anropsrutinen.
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
Du sammanfogar flera gånger stora strängar.
Eftersom strängar är oföränderliga skapar varje strängsammanfogningsåtgärd en ny sträng. Effekten för små strängar, eller för ett litet antal sammanfogningsåtgärder, är försumbar. Men för stora strängar eller ett mycket stort antal sammanlänkningsåtgärder kan strängsammanfogning leda till ett stort antal minnesallokeringar och minnesfragmentering, dåliga prestanda och eventuellt OutOfMemoryException undantag.
När du sammanfogar stora strängar eller utför ett stort antal sammanlänkningsåtgärder bör du använda StringBuilder klassen i stället för String klassen. När du har manipulerat strängen konverterar du instansen StringBuilder till en sträng genom att anropa StringBuilder.ToString metoden.
Du fäster ett stort antal objekt i minnet.
Att fästa ett stort antal objekt i minnet under långa perioder kan göra det svårt för skräpinsamlaren att allokera sammanhängande minnesblock. Om du har fäst ett stort antal objekt i minnet, till exempel med hjälp av -instruktionen fixed i C# eller genom att anropa GCHandle.Alloc(Object, GCHandleType) metoden med en referenstyp av GCHandleType.Pinned, kan du göra följande för att åtgärda OutOfMemoryException undantaget.
Utvärdera om varje objekt verkligen behöver fästas,
Se till att varje objekt är ofäst så snart som möjligt.
Kontrollera att varje anrop till GCHandle.Alloc(Object, GCHandleType) metoden för att fästa minne har ett motsvarande anrop till GCHandle.Free metoden för att ta bort minnet.
Följande Microsoft mellanliggande instruktioner (MSIL) genererar ett OutOfMemoryException undantag:
Konstruktorer
| Name | Description |
|---|---|
| OutOfMemoryException() |
Initierar en ny instans av OutOfMemoryException klassen. |
| OutOfMemoryException(SerializationInfo, StreamingContext) |
Initierar en ny instans av OutOfMemoryException klassen med serialiserade data. |
| OutOfMemoryException(String, Exception) |
Initierar en ny instans av OutOfMemoryException klassen med ett angivet felmeddelande och en referens till det inre undantaget som är orsaken till det här undantaget. |
| OutOfMemoryException(String) |
Initierar en ny instans av OutOfMemoryException klassen med ett angivet felmeddelande. |
Egenskaper
| Name | Description |
|---|---|
| Data |
Hämtar en samling nyckel/värde-par som ger ytterligare användardefinierad information om undantaget. (Ärvd från Exception) |
| HelpLink |
Hämtar eller anger en länk till hjälpfilen som är associerad med det här undantaget. (Ärvd från Exception) |
| HResult |
Hämtar eller anger HRESULT, ett kodat numeriskt värde som har tilldelats ett specifikt undantag. (Ärvd från Exception) |
| InnerException |
Hämtar den Exception instans som orsakade det aktuella undantaget. (Ärvd från Exception) |
| Message |
Hämtar ett meddelande som beskriver det aktuella undantaget. (Ärvd från Exception) |
| Source |
Hämtar eller anger namnet på programmet eller objektet som orsakar felet. (Ärvd från Exception) |
| StackTrace |
Hämtar en strängrepresentation av de omedelbara ramarna i anropsstacken. (Ärvd från Exception) |
| TargetSite |
Hämtar den metod som utlöser det aktuella undantaget. (Ärvd från Exception) |
Metoder
| Name | Description |
|---|---|
| Equals(Object) |
Avgör om det angivna objektet är lika med det aktuella objektet. (Ärvd från Object) |
| GetBaseException() |
När den åsidosätts i en härledd klass returnerar den Exception som är rotorsaken till ett eller flera efterföljande undantag. (Ärvd från Exception) |
| GetHashCode() |
Fungerar som standard-hash-funktion. (Ärvd från Object) |
| GetObjectData(SerializationInfo, StreamingContext) |
När åsidosättas i en härledd klass anger du SerializationInfo med information om undantaget. (Ärvd från Exception) |
| GetType() |
Hämtar körningstypen för den aktuella instansen. (Ärvd från Exception) |
| MemberwiseClone() |
Skapar en ytlig kopia av den aktuella Object. (Ärvd från Object) |
| ToString() |
Skapar och returnerar en strängrepresentation av det aktuella undantaget. (Ärvd från Exception) |
Händelser
| Name | Description |
|---|---|
| SerializeObjectState |
Inträffar när ett undantag serialiseras för att skapa ett undantagstillståndsobjekt som innehåller serialiserade data om undantaget. (Ärvd från Exception) |