OutOfMemoryException Classe
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Eccezione generata quando non vi è memoria sufficiente per continuare l'esecuzione di un programma.
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
- Ereditarietà
- Ereditarietà
- Derivato
- Attributi
Commenti
OutOfMemoryException usa HRESULT COR_E_OUTOFMEMORY
, che ha il valore 0x8007000E.
Per un elenco di valori di proprietà iniziali per un'istanza di OutOfMemoryException, vedere il OutOfMemoryException costruttori.
Nota
Il valore della proprietà ereditata Data è sempre null
.
Un'eccezione OutOfMemoryException ha due cause principali:
Si sta tentando di espandere un StringBuilder oggetto oltre la lunghezza definita dalla relativa StringBuilder.MaxCapacity proprietà.
Common Language Runtime non può allocare memoria contigua sufficiente per eseguire correttamente un'operazione. Questa eccezione può essere generata da qualsiasi assegnazione di proprietà o chiamata al metodo che richiede un'allocazione di memoria. Per altre informazioni sulla causa dell'eccezione OutOfMemoryException , vedere il post di blog "Memoria insufficiente" non fa riferimento alla memoria fisica.
Questo tipo di OutOfMemoryException eccezione rappresenta un errore irreversibile. Se si sceglie di gestire l'eccezione, è necessario includere un
catch
blocco che chiama il Environment.FailFast metodo per terminare l'app e aggiungere una voce al registro eventi di sistema, come illustrato nell'esempio seguente.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...
Alcune delle condizioni in cui viene generata l'eccezione e le azioni che è possibile eseguire per eliminarle includono quanto segue:
Si sta chiamando il StringBuilder.Insert metodo.
Si sta tentando di aumentare la lunghezza di un StringBuilder oggetto oltre le dimensioni specificate dalla relativa StringBuilder.MaxCapacity proprietà. Nell'esempio seguente viene illustrata l'eccezione OutOfMemoryException generata da una chiamata al StringBuilder.Insert(Int32, String, Int32) metodo quando l'esempio tenta di inserire una stringa che causerebbe il superamento della capacità massima della proprietà dell'oggetto Length .
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.
È possibile eseguire una delle operazioni seguenti per risolvere l'errore:
Sostituire la chiamata al StringBuilder.StringBuilder(Int32, Int32) costruttore con una chiamata a qualsiasi altro StringBuilder overload del costruttore. La capacità massima dell'oggetto StringBuilder verrà impostata sul valore predefinito, ovvero Int32.MaxValue.
Chiamare il StringBuilder.StringBuilder(Int32, Int32) costruttore con un
maxCapacity
valore sufficientemente grande per supportare eventuali espansioni all'oggetto StringBuilder .
L'app viene eseguita come processo a 32 bit.
I processi a 32 bit possono allocare un massimo di 2 GB di memoria in modalità utente virtuale nei sistemi a 32 bit e 4 GB di memoria in modalità utente virtuale nei sistemi a 64 bit. Ciò può rendere più difficile per Common Language Runtime allocare memoria contigua sufficiente quando è necessaria un'allocazione di grandi dimensioni. Al contrario, i processi a 64 bit possono allocare fino a 8 TB di memoria virtuale. Per risolvere questa eccezione, ricompilare l'app per indirizzare una piattaforma a 64 bit. Per informazioni sulla destinazione di piattaforme specifiche in Visual Studio, vedere Procedura: Configurare progetti in piattaforme di destinazione.
L'app perde risorse non gestite
Anche se il Garbage Collector è in grado di liberare memoria allocata ai tipi gestiti, non gestisce la memoria allocata alle risorse non gestite, ad esempio handle del sistema operativo (inclusi handle ai file, file mappati alla memoria, pipe, chiavi del Registro di sistema e handle di attesa) e blocchi di memoria allocati direttamente dalle chiamate API Windows o dalle chiamate alle funzioni di allocazione della memoria, ad esempio malloc
. I tipi che usano risorse non gestite implementano l'interfaccia IDisposable .
Se si usa un tipo che usa risorse non gestite, è necessario assicurarsi di chiamare il IDisposable.Dispose relativo metodo al termine dell'uso. Alcuni tipi implementano anche un Close
metodo identico nella funzione a un Dispose
metodo. Per altre informazioni, vedere l'argomento Uso di oggetti che implementano IDisposable .
Se è stato creato un tipo che usa risorse non gestite, assicurarsi di aver implementato il modello Dispose e, se necessario, fornito un finalizzatore. Per altre informazioni, vedere Implementazione di un metodo Dispose e Object.Finalize.
Si sta tentando di creare una matrice di grandi dimensioni in un processo a 64 bit
Per impostazione predefinita, Common Language Runtime in .NET Framework non consente singoli oggetti le cui dimensioni superano 2 GB. Per eseguire l'override di questa impostazione predefinita, è possibile usare l'impostazione <del file di configurazione gcAllowVeryLargeObjects> per abilitare le matrici le cui dimensioni totali superano 2 GB. In .NET Core il supporto per le matrici di dimensioni superiori a 2 GB è abilitato per impostazione predefinita.
Si riguardano set di dati di grandi dimensioni, ad esempio matrici, raccolte o set di dati di database, in memoria.
Quando le strutture di dati o i set di dati che risiedono in memoria diventano così grandi che Common Language Runtime non è in grado di allocare memoria contigua sufficiente per loro, un'eccezione OutOfMemoryException risultati.
Per evitare le eccezioni, è necessario modificare l'applicazione OutOfMemoryException in modo che meno dati si trovino in memoria o che i dati siano suddivisi in segmenti che richiedono allocazioni di memoria più piccole. Ad esempio:
Se si recuperano tutti i dati da un database e quindi lo si filtra nell'app per ridurre al minimo i viaggi al server, è necessario modificare le query per restituire solo il subset di dati necessari per l'app. Quando si usano tabelle di grandi dimensioni, più query sono quasi sempre più efficienti rispetto al recupero di tutti i dati in una singola tabella e quindi alla modifica.
Se si eseguono query che gli utenti creano dinamicamente, è necessario assicurarsi che il numero di record restituiti dalla query sia limitato.
Se si usano matrici di grandi dimensioni o altri oggetti di raccolta le cui dimensioni generano un'eccezione OutOfMemoryException , è necessario modificare l'applicazione per lavorare i dati nei subset anziché usarli tutti contemporaneamente.
L'esempio seguente ottiene una matrice costituita da 200 milioni di valori a virgola mobile e quindi calcola la media. L'output dell'esempio mostra che, poiché l'esempio archivia l'intera matrice in memoria prima di calcolare la media, viene generata un'eccezione 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.
Nell'esempio seguente viene eliminata l'eccezione OutOfMemoryException elaborando i dati in ingresso senza archiviare l'intero set di dati in memoria, serializzando i dati in un file, se necessario per consentire un'ulteriore elaborazione (queste righe vengono commentate nell'esempio, poiché in questo caso producono un file la cui dimensione è maggiore di 1 GB) e restituisce la media calcolata e il numero di casi alla routine chiamante.
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
Si concatenano ripetutamente stringhe di grandi dimensioni.
Poiché le stringhe sono non modificabili, ogni operazione di concatenazione stringa crea una nuova stringa. L'impatto per stringhe piccole o per un numero ridotto di operazioni di concatenazione è trascurabile. Tuttavia, per stringhe di grandi dimensioni o un numero molto elevato di operazioni di concatenazione, la concatenazione di stringhe può causare un numero elevato di allocazioni di memoria e frammentazione della memoria, prestazioni ridotte e possibilmente OutOfMemoryException eccezioni.
Quando si concatenano stringhe di grandi dimensioni o si eseguono un numero elevato di operazioni di concatenazione, è consigliabile usare la classe anziché la StringBuilderString classe. Al termine della modifica della stringa, convertire l'istanza StringBuilder in una stringa chiamando il StringBuilder.ToString metodo .
È possibile aggiungere un numero elevato di oggetti in memoria.
L'aggiunta di un numero elevato di oggetti in memoria per periodi lunghi può rendere difficile l'allocazione di blocchi contigui di memoria da parte del Garbage Collector. Se è stato aggiunto un numero elevato di oggetti in memoria, ad esempio usando l'istruzione fixed
in C# o chiamando il GCHandle.Alloc(Object, GCHandleType) metodo con un tipo di handle di GCHandleType.Pinned, è possibile eseguire le operazioni seguenti per risolvere l'eccezione OutOfMemoryException .
Valutare se ogni oggetto deve essere aggiunto in realtà,
Assicurarsi che ogni oggetto venga rimosso il prima possibile.
Assicurarsi che ogni chiamata al GCHandle.Alloc(Object, GCHandleType) metodo per aggiungere la memoria abbia una chiamata corrispondente al GCHandle.Free metodo per rimuovere tale memoria.
Le istruzioni microsoft intermedie (MSIL) seguenti generano un'eccezione OutOfMemoryException :
Costruttori
OutOfMemoryException() |
Inizializza una nuova istanza della classe OutOfMemoryException. |
OutOfMemoryException(SerializationInfo, StreamingContext) |
Obsoleti.
Inizializza una nuova istanza della classe OutOfMemoryException con dati serializzati. |
OutOfMemoryException(String) |
Inizializza una nuova istanza della classe OutOfMemoryException con un messaggio di errore specificato. |
OutOfMemoryException(String, Exception) |
Inizializza una nuova istanza della classe OutOfMemoryException con un messaggio di errore specificato e un riferimento all'eccezione interna che è la causa dell'eccezione corrente. |
Proprietà
Data |
Ottiene una raccolta di coppie chiave/valore che forniscono informazioni definite dall'utente aggiuntive sull'eccezione. (Ereditato da Exception) |
HelpLink |
Ottiene o imposta un collegamento al file della Guida associato all'eccezione. (Ereditato da Exception) |
HResult |
Ottiene o imposta HRESULT, un valore numerico codificato che viene assegnato a un'eccezione specifica. (Ereditato da Exception) |
InnerException |
Ottiene l'istanza di Exception che ha causato l'eccezione corrente. (Ereditato da Exception) |
Message |
Ottiene un messaggio che descrive l'eccezione corrente. (Ereditato da Exception) |
Source |
Ottiene o imposta il nome dell'oggetto o dell'applicazione che ha generato l'errore. (Ereditato da Exception) |
StackTrace |
Ottiene una rappresentazione di stringa dei frame immediati nello stack di chiamate. (Ereditato da Exception) |
TargetSite |
Ottiene il metodo che genera l'eccezione corrente. (Ereditato da Exception) |
Metodi
Equals(Object) |
Determina se l'oggetto specificato è uguale all'oggetto corrente. (Ereditato da Object) |
GetBaseException() |
Quando ne viene eseguito l'override in una classe derivata, restituisce l'Exception che è la causa radice di una o più eccezioni successive. (Ereditato da Exception) |
GetHashCode() |
Funge da funzione hash predefinita. (Ereditato da Object) |
GetObjectData(SerializationInfo, StreamingContext) |
Obsoleti.
Quando ne viene eseguito l'override in una classe derivata, imposta il controllo SerializationInfo con le informazioni sull'eccezione. (Ereditato da Exception) |
GetType() |
Ottiene il tipo di runtime dell'istanza corrente. (Ereditato da Exception) |
MemberwiseClone() |
Crea una copia superficiale dell'oggetto Object corrente. (Ereditato da Object) |
ToString() |
Crea e restituisce una rappresentazione di stringa dell'eccezione corrente. (Ereditato da Exception) |
Eventi
SerializeObjectState |
Obsoleti.
Si verifica quando un'eccezione viene serializzata per creare un oggetto di stato eccezione contenente i dati serializzati relativi all'eccezione. (Ereditato da Exception) |