OutOfMemoryException Clase
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Excepción que se produce cuando no hay suficiente memoria para continuar con la ejecución de un programa.
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
- Herencia
- Herencia
- Derivado
- Atributos
Comentarios
OutOfMemoryException usa HRESULT COR_E_OUTOFMEMORY
, que tiene el valor 0x8007000E.
Para obtener una lista de valores de propiedad iniciales de una instancia de OutOfMemoryException, consulte el OutOfMemoryException constructores.
Nota
El valor de la propiedad heredada Data siempre null
es .
Una OutOfMemoryException excepción tiene dos causas principales:
Está intentando expandir un StringBuilder objeto más allá de la longitud definida por su StringBuilder.MaxCapacity propiedad .
Common Language Runtime no puede asignar suficiente memoria contigua para realizar correctamente una operación. Esta excepción se puede producir mediante cualquier llamada de método o asignación de propiedades que requiera una asignación de memoria. Para obtener más información sobre la causa de la OutOfMemoryException excepción, vea la entrada de blog "Memoria insuficiente" No hace referencia a la memoria física.
Este tipo de OutOfMemoryException excepción representa un error catastrófico. Si decide controlar la excepción, debe incluir un
catch
bloque que llame al método para finalizar la Environment.FailFast aplicación y agregar una entrada al registro de eventos del sistema, como se muestra en el ejemplo siguiente.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...
Algunas de las condiciones en las que se produce la excepción y las acciones que puede realizar para eliminarla incluyen lo siguiente:
Está llamando al StringBuilder.Insert método .
Está intentando aumentar la longitud de un StringBuilder objeto más allá del tamaño especificado por su StringBuilder.MaxCapacity propiedad. En el ejemplo siguiente se muestra la OutOfMemoryException excepción producida por una llamada al StringBuilder.Insert(Int32, String, Int32) método cuando el ejemplo intenta insertar una cadena que haría que la propiedad del Length objeto supere su capacidad máxima.
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.
Puede hacer cualquiera de las siguientes acciones para solucionar el error:
Reemplace la llamada al StringBuilder.StringBuilder(Int32, Int32) constructor por una llamada a cualquier otra StringBuilder sobrecarga del constructor. La capacidad máxima del StringBuilder objeto se establecerá en su valor predeterminado, que es Int32.MaxValue.
Llame al StringBuilder.StringBuilder(Int32, Int32) constructor con un
maxCapacity
valor lo suficientemente grande como para acomodar las expansiones al StringBuilder objeto .
La aplicación se ejecuta como un proceso de 32 bits.
Los procesos de 32 bits pueden asignar un máximo de 2 GB de memoria en modo usuario virtual en sistemas de 32 bits y 4 GB de memoria en modo usuario virtual en sistemas de 64 bits. Esto puede dificultar que Common Language Runtime asigne suficiente memoria contigua cuando se necesite una asignación grande. En cambio, los procesos de 64 bits pueden asignar hasta 8 TB de memoria virtual. Para solucionar esta excepción, vuelva a compilar la aplicación para tener como destino una plataforma de 64 bits. Para obtener información sobre el destino de plataformas específicas en Visual Studio, vea Cómo: Configurar proyectos en plataformas de destino.
La aplicación está filtrando recursos no administrados
Aunque el recolector de elementos no utilizados puede liberar memoria asignada a tipos administrados, no administra la memoria asignada a recursos no administrados, como identificadores del sistema operativo (incluidos identificadores para archivos, archivos asignados a memoria, canalizaciones, claves del Registro y identificadores de espera) y los bloques de memoria asignados directamente por las llamadas API de Windows o por llamadas a funciones de asignación de memoria como malloc
. Los tipos que consumen recursos no administrados implementan la IDisposable interfaz .
Si usa un tipo que usa recursos no administrados, debe asegurarse de llamar a su IDisposable.Dispose método cuando haya terminado de usarlo. (Algunos tipos también implementan un Close
método idéntico en función a un Dispose
método). Para obtener más información, vea el tema Using Objects That Implement IDisposable (Usar objetos que implementan IDisposable ).
Si ha creado un tipo que usa recursos no administrados, asegúrese de que ha implementado el patrón Dispose y, si es necesario, ha proporcionado un finalizador. Para obtener más información, vea Implementación de un método Dispose y Object.Finalize.
Está intentando crear una matriz grande en un proceso de 64 bits.
De forma predeterminada, Common Language Runtime en .NET Framework no permite objetos únicos cuyo tamaño supere los 2 GB. Para invalidar este valor predeterminado, puede usar la configuración del <archivo de configuración gcAllowVeryLargeObjects> para habilitar matrices cuyo tamaño total supere los 2 GB. En .NET Core, la compatibilidad con matrices de más de 2 GB está habilitada de forma predeterminada.
Está trabajando con conjuntos de datos muy grandes (como matrices, colecciones o conjuntos de datos de base de datos) en memoria.
Cuando las estructuras de datos o los conjuntos de datos que residen en la memoria se vuelven tan grandes que Common Language Runtime no puede asignar suficiente memoria contigua para ellos, se produce una OutOfMemoryException excepción.
Para evitar las excepciones, debe modificar la OutOfMemoryException aplicación para que menos datos resida en la memoria o los datos se divida en segmentos que requieran asignaciones de memoria más pequeñas. Por ejemplo:
Si va a recuperar todos los datos de una base de datos y, a continuación, filtrarlos en la aplicación para minimizar los viajes al servidor, debe modificar las consultas para devolver solo el subconjunto de datos que necesita la aplicación. Al trabajar con tablas grandes, varias consultas son casi siempre más eficaces que recuperar todos los datos de una sola tabla y, a continuación, manipularlos.
Si está ejecutando consultas que los usuarios crean dinámicamente, debe asegurarse de que el número de registros devueltos por la consulta es limitado.
Si usa matrices grandes u otros objetos de colección cuyo tamaño da como resultado una OutOfMemoryException excepción, debe modificar la aplicación para que funcione los datos en subconjuntos en lugar de trabajar con él todo a la vez.
En el ejemplo siguiente se obtiene una matriz que consta de 200 millones de valores de punto flotante y, a continuación, calcula su media. La salida del ejemplo muestra que, dado que el ejemplo almacena toda la matriz en memoria antes de calcular la media, se produce una OutOfMemoryException excepción .
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.
En el ejemplo siguiente se elimina la OutOfMemoryException excepción procesando los datos entrantes sin almacenar todo el conjunto de datos en la memoria, serializando los datos en un archivo si es necesario para permitir el procesamiento adicional (estas líneas se comentan en el ejemplo, ya que en este caso producen un archivo cuyo tamaño es mayor que 1 GB) y devuelven la media calculada y el número de casos a la rutina de llamada.
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
Va a concatenar repetidamente cadenas grandes.
Dado que las cadenas son inmutables, cada operación de concatenación de cadenas crea una nueva cadena. El impacto de las cadenas pequeñas, o para un pequeño número de operaciones de concatenación, es insignificante. Pero para cadenas grandes o un gran número de operaciones de concatenación, la concatenación de cadenas puede provocar un gran número de asignaciones de memoria y fragmentación de memoria, un rendimiento deficiente y, posiblemente OutOfMemoryException , excepciones.
Al concatenar cadenas grandes o realizar un gran número de operaciones de concatenación, debe usar la StringBuilder clase en lugar de la String clase . Cuando haya terminado de manipular la cadena, convierta la StringBuilder instancia en una cadena llamando al StringBuilder.ToString método .
Ancla un gran número de objetos en memoria.
Anclar un gran número de objetos en memoria durante largos períodos puede dificultar que el recolector de elementos no utilizados asigne bloques contiguos de memoria. Si ha anclado un gran número de objetos en memoria, por ejemplo, mediante la fixed
instrucción en C# o llamando al GCHandle.Alloc(Object, GCHandleType) método con un tipo de identificador de GCHandleType.Pinned, puede hacer lo siguiente para solucionar la OutOfMemoryException excepción.
Evalúe si realmente es necesario anclar cada objeto,
Asegúrese de que cada objeto esté desanclado lo antes posible.
Asegúrese de que cada llamada al GCHandle.Alloc(Object, GCHandleType) método para anclar memoria tiene una llamada correspondiente al GCHandle.Free método para desanclar esa memoria.
Las siguientes instrucciones intermedias de Microsoft (MSIL) producen una OutOfMemoryException excepción:
Constructores
OutOfMemoryException() |
Inicializa una nueva instancia de la clase OutOfMemoryException. |
OutOfMemoryException(SerializationInfo, StreamingContext) |
Obsoletos.
Inicializa una nueva instancia de la clase OutOfMemoryException con datos serializados. |
OutOfMemoryException(String) |
Inicializa una nueva instancia de la clase OutOfMemoryException con el mensaje de error especificado. |
OutOfMemoryException(String, Exception) |
Inicializa una nueva instancia de la clase OutOfMemoryException con el mensaje de error especificado y una referencia a la excepción interna que representa la causa de esta excepción. |
Propiedades
Data |
Obtiene una colección de pares clave/valor que proporciona información definida por el usuario adicional sobre la excepción. (Heredado de Exception) |
HelpLink |
Obtiene o establece un vínculo al archivo de ayuda asociado a esta excepción. (Heredado de Exception) |
HResult |
Obtiene o establece HRESULT, un valor numérico codificado que se asigna a una excepción específica. (Heredado de Exception) |
InnerException |
Obtiene la instancia Exception que produjo la excepción actual. (Heredado de Exception) |
Message |
Obtiene un mensaje que describe la excepción actual. (Heredado de Exception) |
Source |
Devuelve o establece el nombre de la aplicación o del objeto que generó el error. (Heredado de Exception) |
StackTrace |
Obtiene una representación de cadena de los marcos inmediatos en la pila de llamadas. (Heredado de Exception) |
TargetSite |
Obtiene el método que produjo la excepción actual. (Heredado de Exception) |
Métodos
Equals(Object) |
Determina si el objeto especificado es igual que el objeto actual. (Heredado de Object) |
GetBaseException() |
Cuando se invalida en una clase derivada, devuelve la clase Exception que representa la causa principal de una o más excepciones posteriores. (Heredado de Exception) |
GetHashCode() |
Sirve como la función hash predeterminada. (Heredado de Object) |
GetObjectData(SerializationInfo, StreamingContext) |
Obsoletos.
Cuando se invalida en una clase derivada, establece SerializationInfo con información sobre la excepción. (Heredado de Exception) |
GetType() |
Obtiene el tipo de tiempo de ejecución de la instancia actual. (Heredado de Exception) |
MemberwiseClone() |
Crea una copia superficial del Object actual. (Heredado de Object) |
ToString() |
Crea y devuelve una representación de cadena de la excepción actual. (Heredado de Exception) |
Eventos
SerializeObjectState |
Obsoletos.
Ocurre cuando una excepción se serializa para crear un objeto de estado de excepción que contenga datos serializados sobre la excepción. (Heredado de Exception) |