OutOfMemoryException Klas
Definitie
Belangrijk
Bepaalde informatie heeft betrekking op een voorlopige productversie die aanzienlijk kan worden gewijzigd voordat deze wordt uitgebracht. Microsoft biedt geen enkele expliciete of impliciete garanties met betrekking tot de informatie die hier wordt verstrekt.
De uitzondering die wordt gegenereerd wanneer er onvoldoende geheugen is om de uitvoering van een programma voort te zetten.
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
- Overname
- Overname
- Afgeleid
- Kenmerken
Opmerkingen
OutOfMemoryException maakt gebruik van HRESULT COR_E_OUTOFMEMORY, met de waarde 0x8007000E.
Voor een lijst van initiële eigenschapswaarden voor een exemplaar van OutOfMemoryException, zie de OutOfMemoryException-constructoren.
Note
De waarde van de overgenomen Data eigenschap is altijd null.
Een OutOfMemoryException uitzondering heeft twee belangrijke oorzaken:
U probeert een StringBuilder object uit te breiden buiten de lengte die is gedefinieerd door StringBuilder.MaxCapacity de eigenschap.
De algemene taalruntime kan onvoldoende aaneengesloten geheugen toewijzen om een bewerking uit te voeren. Deze uitzondering kan worden gegenereerd door een eigenschapstoewijzing of methode-aanroep waarvoor een geheugentoewijzing is vereist. Zie het blogbericht OutOfMemoryException meer informatie over de oorzaak van de uitzondering.
Dit type OutOfMemoryException uitzondering vertegenwoordigt een onherstelbare fout. Als u ervoor kiest om de uitzondering af te handelen, moet u een
catchblok opnemen waarmee de methode wordt aangeroepen om uw Environment.FailFast app te beëindigen en een vermelding toe te voegen aan het systeemlogboek, zoals in het volgende voorbeeld.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...
Enkele van de voorwaarden waaronder de uitzondering wordt gegenereerd en de acties die u kunt ondernemen om deze te elimineren, zijn onder andere:
U roept de StringBuilder.Insert methode aan.
U probeert de lengte van een StringBuilder object groter te maken dan de grootte die is opgegeven door StringBuilder.MaxCapacity de eigenschap. In het volgende voorbeeld ziet u de OutOfMemoryException uitzondering die wordt gegenereerd door een aanroep naar de StringBuilder.Insert(Int32, String, Int32) methode wanneer in het voorbeeld wordt geprobeerd een tekenreeks in te voegen waardoor de eigenschap van Length het object de maximale capaciteit overschrijdt.
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.
U kunt een van de volgende handelingen uitvoeren om de fout op te pakken:
Vervang de aanroep van de StringBuilder.StringBuilder(Int32, Int32) constructor door een andere overbelasting van een constructor StringBuilder . De maximale capaciteit van uw StringBuilder object wordt ingesteld op de standaardwaarde.Int32.MaxValue
Roep de StringBuilder.StringBuilder(Int32, Int32) constructor aan met een
maxCapacitywaarde die groot genoeg is om eventuele uitbreidingen naar het StringBuilder object toe te passen.
Uw app wordt uitgevoerd als een 32-bits proces.
32-bits processen kunnen maximaal 2 GB aan geheugen in de virtuele gebruikersmodus toewijzen op 32-bits systemen en 4 GB aan geheugen in de virtuele gebruikersmodus op 64-bits systemen. Dit kan het lastiger maken voor de algemene taalruntime om voldoende aaneengesloten geheugen toe te wijzen wanneer een grote toewijzing nodig is. 64-bits processen kunnen daarentegen maximaal 8 TB aan virtueel geheugen toewijzen. Als u deze uitzondering wilt verhelpen, moet u uw app opnieuw compileren om een 64-bits platform te bereiken. Zie Hoe to: Projecten configureren voor doelplatforms voor meer informatie over het instellen van specifieke platforms in Visual Studio.
Uw app lekt onbeheerde resources
Hoewel de garbagecollector geheugen kan vrijmaken aan beheerde typen, beheert het geen geheugen dat is toegewezen aan niet-beheerde resources, zoals ingangen van het besturingssysteem (inclusief ingangen voor bestanden, geheugentoewijzingen, pijpen, registersleutels en wachtgrepen) en geheugenblokken die rechtstreeks worden toegewezen door Windows API-aanroepen of door aanroepen naar geheugentoewijzingsfuncties zoals malloc. Typen die onbeheerde resources verbruiken, implementeren de IDisposable interface.
Als u een type gebruikt dat gebruikmaakt van niet-beheerde resources, moet u de bijbehorende methode aanroepen IDisposable.Dispose wanneer u klaar bent met het gebruik ervan. (Sommige typen implementeren ook een Close methode die identiek is aan een Dispose methode.) Zie het onderwerp Using Objects That Implement IDisposable (Objecten gebruiken die IDisposable implementeren ) voor meer informatie.
Als u een type hebt gemaakt dat gebruikmaakt van niet-beheerde resources, moet u ervoor zorgen dat u het verwijderingspatroon hebt geïmplementeerd en, indien nodig, een finalizer hebt opgegeven. Zie Een verwijderingsmethode implementeren en Object.Finalizevoor meer informatie.
U probeert een grote matrix te maken in een 64-bits proces
Standaard staat de algemene taalruntime in .NET Framework geen enkele objecten toe waarvan de grootte groter is dan 2 GB. Als u deze standaardinstelling wilt overschrijven, kunt u de <instelling gcAllowVeryLargeObjects-configuratiebestand gebruiken om matrices> in te schakelen waarvan de totale grootte groter is dan 2 GB. Op .NET Core is ondersteuning voor matrices van meer dan 2 GB standaard ingeschakeld.
U werkt met zeer grote gegevenssets (zoals matrices, verzamelingen of databasegegevenssets) in het geheugen.
Wanneer gegevensstructuren of gegevenssets die zich in het geheugen bevinden zo groot worden dat de algemene taalruntime er onvoldoende aaneengesloten geheugen voor kan toewijzen, is er een OutOfMemoryException uitzonderingsresultaat.
Als u de OutOfMemoryException uitzonderingen wilt voorkomen, moet u uw toepassing wijzigen zodat er minder gegevens in het geheugen aanwezig zijn of dat de gegevens zijn onderverdeeld in segmenten waarvoor kleinere geheugentoewijzingen zijn vereist. Voorbeeld:
Als u alle gegevens opvraagt uit een database en deze vervolgens in uw app filtert om reizen naar de server te minimaliseren, moet u uw query's wijzigen om alleen de subset met gegevens te retourneren die uw app nodig heeft. Wanneer u met grote tabellen werkt, zijn meerdere query's bijna altijd efficiënter dan het ophalen van alle gegevens in één tabel en het bewerken ervan.
Als u query's uitvoert die gebruikers dynamisch maken, moet u ervoor zorgen dat het aantal records dat door de query wordt geretourneerd, beperkt is.
Als u grote matrices of andere verzamelingsobjecten gebruikt waarvan de grootte resulteert in een OutOfMemoryException uitzondering, moet u uw toepassing aanpassen om de gegevens in subsets te bewerken in plaats van allemaal tegelijk ermee te werken.
In het volgende voorbeeld wordt een matrix opgehaald die uit 200 miljoen drijvendekommawaarden bestaat en vervolgens het gemiddelde berekent. In de uitvoer van het voorbeeld ziet u dat, omdat in het voorbeeld de hele matrix in het geheugen wordt opgeslagen voordat het gemiddelde wordt berekend, wordt er een OutOfMemoryException gegenereerd.
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.
Het volgende voorbeeld elimineert de OutOfMemoryException uitzondering door de binnenkomende gegevens te verwerken zonder de volledige gegevensset in het geheugen op te slaan, de gegevens indien nodig te serialiseren naar een bestand om verdere verwerking toe te staan (deze regels worden in het voorbeeld als commentaar gegeven, omdat ze in dit geval een bestand produceren waarvan de grootte groter is dan 1 GB) en het berekende gemiddelde en het aantal gevallen retourneren aan de aanroepende routine.
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
U voegt herhaaldelijk grote tekenreeksen samen.
Omdat tekenreeksen onveranderbaar zijn, maakt elke samenvoegbewerking een nieuwe tekenreeks. De gevolgen voor kleine tekenreeksen of voor een klein aantal samenvoegingsbewerkingen zijn te verwaarlozen. Maar voor grote tekenreeksen of een zeer groot aantal samenvoegingsbewerkingen kan tekenreekssamenvoeging leiden tot een groot aantal geheugentoewijzingen en geheugenfragmentatie, slechte prestaties en mogelijk OutOfMemoryException uitzonderingen.
Wanneer u grote tekenreeksen samenvoegt of een groot aantal samenvoegingsbewerkingen uitvoert, moet u de StringBuilder klasse gebruiken in plaats van de String klasse. Wanneer u klaar bent met het bewerken van de tekenreeks, converteert u het StringBuilder exemplaar naar een tekenreeks door de methode aan te StringBuilder.ToString roepen.
U kunt een groot aantal objecten vastmaken in het geheugen.
Het vastmaken van een groot aantal objecten in het geheugen voor lange perioden kan het lastig maken voor de garbagecollector om aaneengesloten blokken geheugen toe te wijzen. Als u een groot aantal objecten in het geheugen hebt vastgemaakt, bijvoorbeeld met behulp van de fixed instructie in C# of door de GCHandle.Alloc(Object, GCHandleType) methode aan te roepen met een handletype GCHandleType.Pinned, kunt u het volgende doen om de OutOfMemoryException uitzondering aan te pakken.
Evalueren of elk object echt moet worden vastgemaakt,
Zorg ervoor dat elk object zo snel mogelijk is losgemaakt.
Zorg ervoor dat elke aanroep naar de methode voor het GCHandle.Alloc(Object, GCHandleType) vastmaken van geheugen een bijbehorende aanroep van de GCHandle.Free methode heeft om dat geheugen los te maken.
De volgende Microsoft tussenliggende instructies (MSIL) genereren een OutOfMemoryException uitzondering:
Constructors
| Name | Description |
|---|---|
| OutOfMemoryException() |
Initialiseert een nieuw exemplaar van de OutOfMemoryException klasse. |
| OutOfMemoryException(SerializationInfo, StreamingContext) |
Verouderd.
Initialiseert een nieuw exemplaar van de OutOfMemoryException klasse met geserialiseerde gegevens. |
| OutOfMemoryException(String, Exception) |
Initialiseert een nieuw exemplaar van de OutOfMemoryException klasse met een opgegeven foutbericht en een verwijzing naar de binnenste uitzondering die de oorzaak van deze uitzondering is. |
| OutOfMemoryException(String) |
Initialiseert een nieuw exemplaar van de OutOfMemoryException klasse met een opgegeven foutbericht. |
Eigenschappen
| Name | Description |
|---|---|
| Data |
Hiermee haalt u een verzameling sleutel-waardeparen op die aanvullende door de gebruiker gedefinieerde informatie over de uitzondering bieden. (Overgenomen van Exception) |
| HelpLink |
Hiermee haalt u een koppeling op naar het Help-bestand dat aan deze uitzondering is gekoppeld. (Overgenomen van Exception) |
| HResult |
Hiermee wordt HRESULT opgehaald of ingesteld, een gecodeerde numerieke waarde die is toegewezen aan een specifieke uitzondering. (Overgenomen van Exception) |
| InnerException |
Hiermee haalt u het Exception exemplaar op dat de huidige uitzondering heeft veroorzaakt. (Overgenomen van Exception) |
| Message |
Hiermee wordt een bericht weergegeven waarin de huidige uitzondering wordt beschreven. (Overgenomen van Exception) |
| Source |
Hiermee wordt de naam van de toepassing of het object dat de fout veroorzaakt, opgehaald of ingesteld. (Overgenomen van Exception) |
| StackTrace |
Hiermee haalt u een tekenreeksweergave van de directe frames op de aanroepstack op. (Overgenomen van Exception) |
| TargetSite |
Hiermee haalt u de methode op waarmee de huidige uitzondering wordt gegenereerd. (Overgenomen van Exception) |
Methoden
| Name | Description |
|---|---|
| Equals(Object) |
Bepaalt of het opgegeven object gelijk is aan het huidige object. (Overgenomen van Object) |
| GetBaseException() |
Wanneer deze wordt overschreven in een afgeleide klasse, retourneert u de Exception hoofdoorzaak van een of meer volgende uitzonderingen. (Overgenomen van Exception) |
| GetHashCode() |
Fungeert als de standaardhashfunctie. (Overgenomen van Object) |
| GetObjectData(SerializationInfo, StreamingContext) |
Verouderd.
Wanneer deze wordt overschreven in een afgeleide klasse, stelt u de SerializationInfo met informatie over de uitzondering in. (Overgenomen van Exception) |
| GetType() |
Hiermee haalt u het runtimetype van het huidige exemplaar op. (Overgenomen van Exception) |
| MemberwiseClone() |
Hiermee maakt u een ondiepe kopie van de huidige Object. (Overgenomen van Object) |
| ToString() |
Hiermee maakt en retourneert u een tekenreeksweergave van de huidige uitzondering. (Overgenomen van Exception) |
gebeurtenis
| Name | Description |
|---|---|
| SerializeObjectState |
Verouderd.
Treedt op wanneer een uitzondering wordt geserialiseerd om een uitzonderingsstatusobject te maken dat geserialiseerde gegevens over de uitzondering bevat. (Overgenomen van Exception) |