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 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 el COR_E_OUTOFMEMORY
HRESULT , que tiene el valor 0x8007000E.
Para obtener una lista de valores de propiedad iniciales para una instancia de OutOfMemoryException, vea los constructores de OutOfMemoryException.
Nota
El valor de la propiedad Data heredada siempre es null
.
Una excepción de OutOfMemoryException tiene dos causas principales:
Está intentando expandir un objeto StringBuilder más allá de la longitud definida por su propiedad StringBuilder.MaxCapacity.
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 excepción de OutOfMemoryException, consulte la entrada de blog "Memoria insuficiente" No hace referencia a la memoria física.
Este tipo de excepción de OutOfMemoryException representa un error catastrófico. Si decide controlar la excepción, debe incluir un bloque de
catch
que llame al método Environment.FailFast para finalizar la aplicación y agregar una entrada al registro de eventos del sistema, como hace 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 las siguientes:
Está llamando al método StringBuilder.Insert.
Está intentando aumentar la longitud de un objeto de StringBuilder más allá del tamaño especificado por su propiedad StringBuilder.MaxCapacity. En el ejemplo siguiente se muestra la excepción de OutOfMemoryException producida por una llamada al método StringBuilder.Insert(Int32, String, Int32) cuando el ejemplo intenta insertar una cadena que haría que la propiedad Length del 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 realizar cualquiera de las siguientes acciones para solucionar el error:
Reemplace la llamada al constructor de StringBuilder.StringBuilder(Int32, Int32) por una llamada a cualquier otra sobrecarga del constructor StringBuilder. La capacidad máxima del objeto StringBuilder se establecerá en su valor predeterminado, que es Int32.MaxValue.
Llame al constructor StringBuilder.StringBuilder(Int32, Int32) con un valor de
maxCapacity
lo suficientemente grande como para acomodar las expansiones al objeto StringBuilder.
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 de 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, consulte 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 de archivos, archivos asignados a memoria, canalizaciones, claves del Registro y controladores de espera) y bloques de memoria asignados directamente por 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 interfaz IDisposable.
Si usa un tipo que usa recursos no administrados, debe asegurarse de llamar a su método IDisposable.Dispose cuando haya terminado de usarlo. (Algunos tipos también implementan un método Close
idéntico en función a un método Dispose
). Para obtener más información, vea el tema Using Objects That Implement 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, proporcionó 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
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 excepción de OutOfMemoryException.
Para evitar las excepciones de OutOfMemoryException, debe modificar la 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 casi siempre son 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 excepción de OutOfMemoryException, 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 un 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.
En el ejemplo siguiente se elimina la excepción de OutOfMemoryException procesando los datos entrantes sin almacenar todo el conjunto de datos en 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 generan 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
Se concatenan repetidamente cadenas grandes.
Dado que las cadenas son inmutables, cada operación de concatenación de cadenas crea una nueva cadena. El impacto de 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 clase StringBuilder en lugar de la clase String. Cuando haya terminado de manipular la cadena, convierta la instancia de StringBuilder en una cadena llamando al método StringBuilder.ToString.
anclar 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 instrucción fixed
en C# o llamando al método GCHandle.Alloc(Object, GCHandleType) con un tipo de identificador de GCHandleType.Pinned, puede hacer lo siguiente para abordar la excepción OutOfMemoryException.
Evalúe si cada objeto realmente debe anclarse,
Asegúrese de que cada objeto esté desanclado lo antes posible.
Asegúrese de que cada llamada al método GCHandle.Alloc(Object, GCHandleType) para anclar la memoria tiene una llamada correspondiente al método GCHandle.Free para desanclar esa memoria.
Las siguientes instrucciones intermedias de Microsoft (MSIL) inician una excepción de OutOfMemoryException:
- de cuadro de
- newarr
- newobj
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, Exception) |
Inicializa una nueva instancia de la clase OutOfMemoryException con un mensaje de error especificado y una referencia a la excepción interna que es la causa de esta excepción. |
OutOfMemoryException(String) |
Inicializa una nueva instancia de la clase OutOfMemoryException con un mensaje de error especificado. |
Propiedades
Data |
Obtiene una colección de pares clave-valor que proporcionan información adicional definida por el usuario 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 de Exception que provocó la excepción actual. (Heredado de Exception) |
Message |
Obtiene un mensaje que describe la excepción actual. (Heredado de Exception) |
Source |
Obtiene o establece el nombre de la aplicación o el objeto que provoca el error. (Heredado de Exception) |
StackTrace |
Obtiene una representación de cadena de los fotogramas inmediatos en la pila de llamadas. (Heredado de Exception) |
TargetSite |
Obtiene el método que produce la excepción actual. (Heredado de Exception) |
Métodos
Equals(Object) |
Determina si el objeto especificado es igual al objeto actual. (Heredado de Object) |
GetBaseException() |
Cuando se reemplaza en una clase derivada, devuelve el Exception que es la causa principal de una o varias excepciones posteriores. (Heredado de Exception) |
GetHashCode() |
Actúa como función hash predeterminada. (Heredado de Object) |
GetObjectData(SerializationInfo, StreamingContext) |
Obsoletos.
Cuando se reemplaza en una clase derivada, establece el 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 Objectactual. (Heredado de Object) |
ToString() |
Crea y devuelve una representación de cadena de la excepción actual. (Heredado de Exception) |
Eventos
SerializeObjectState |
Obsoletos.
Se produce cuando se serializa una excepción para crear un objeto de estado de excepción que contiene datos serializados sobre la excepción. (Heredado de Exception) |