OutOfMemoryException Clase

Definición

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
OutOfMemoryException
Herencia
OutOfMemoryException
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 nulles .

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:

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)

Se aplica a

Consulte también