OutOfMemoryException Classe
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
A exceção é lançada quando não há memória suficiente para continuar a execução de um programa.
public ref class OutOfMemoryException : Exception
public ref class OutOfMemoryException : SystemException
public class OutOfMemoryException : Exception
[System.Serializable]
public class OutOfMemoryException : SystemException
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class OutOfMemoryException : SystemException
public class OutOfMemoryException : SystemException
type OutOfMemoryException = class
inherit Exception
[<System.Serializable>]
type OutOfMemoryException = class
inherit SystemException
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type OutOfMemoryException = class
inherit SystemException
type OutOfMemoryException = class
inherit SystemException
Public Class OutOfMemoryException
Inherits Exception
Public Class OutOfMemoryException
Inherits SystemException
- Herança
- Herança
- Derivado
- Atributos
Observações
OutOfMemoryException usa o HRESULT COR_E_OUTOFMEMORY, que tem o valor 0x8007000E.
Para obter uma lista dos valores iniciais de propriedade de uma instância de OutOfMemoryException, consulte os construtores de OutOfMemoryException.
Note
O valor da propriedade herdada Data é sempre null.
Uma OutOfMemoryException exceção tem duas causas principais:
Está a tentar expandir um StringBuilder objeto para além do comprimento definido pela sua StringBuilder.MaxCapacity propriedade.
O runtime da linguagem comum não consegue alocar memória contígua suficiente para realizar uma operação com sucesso. Esta exceção pode ser lançada por qualquer atribuição de propriedade ou chamada de método que exija uma alocação de memória. Para mais informações sobre a causa da OutOfMemoryException exceção, consulte o artigo do blogue "Fora de Memória" Não Se Refere à Memória Física.
Este tipo de OutOfMemoryException exceção representa uma falha catastrófica. Se optar por tratar a exceção, deve incluir um
catchbloco que chame o Environment.FailFast método para terminar a sua aplicação e adicionar uma entrada ao registo de eventos do sistema, como faz o exemplo seguinte.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...
Algumas das condições em que a exceção é lançada e as ações que pode tomar para a eliminar incluem as seguintes:
Estás a chamar o StringBuilder.Insert método.
Está a tentar aumentar o comprimento de um StringBuilder objeto para além do tamanho especificado pela sua StringBuilder.MaxCapacity propriedade. O exemplo seguinte ilustra a OutOfMemoryException exceção lançada por uma chamada ao StringBuilder.Insert(Int32, String, Int32) método quando o exemplo tenta inserir uma cadeia que faria com que a propriedade do Length objeto excedesse a sua capacidade 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.
Pode fazer qualquer uma das seguintes opções para resolver o erro:
Substitua a chamada para o StringBuilder.StringBuilder(Int32, Int32) construtor por uma chamada para qualquer outra StringBuilder sobrecarga de construtor. A capacidade máxima do seu StringBuilder objeto será definida para o seu valor padrão, que é Int32.MaxValue.
Chame o StringBuilder.StringBuilder(Int32, Int32) construtor com um
maxCapacityvalor suficientemente grande para acomodar quaisquer expansões do StringBuilder objeto.
A sua aplicação corre como um processo de 32 bits.
Processos de 32 bits podem alocar um máximo de 2GB de memória virtual em modo utilizador em sistemas de 32 bits, e 4GB de memória virtual em modo utilizador em sistemas de 64 bits. Isto pode dificultar que o tempo de execução da linguagem comum aloque memória contígua suficiente quando é necessária uma grande alocação. Em contraste, os processos de 64 bits podem alocar até 8TB de memória virtual. Para resolver esta exceção, recompile a sua aplicação para direcionar uma plataforma de 64 bits. Para informações sobre como direcionar plataformas específicas em Visual Studio, veja Como: Configurar Projetos para Direcionar Plataformas.
A sua aplicação está a vazar recursos não geridos
Embora o coletor de lixo consiga libertar memória alocada a tipos geridos, não gere memória alocada a recursos não geridos, como handles do sistema operativo (incluindo handles para ficheiros, ficheiros mapeados em memória, pipes, chaves de registo e handles de espera) e blocos de memória alocados diretamente por chamadas de API Windows ou por chamadas para funções de alocação de memória como malloc. Os tipos que consomem recursos não geridos implementam a IDisposable interface.
Se estiver a consumir um tipo que utiliza recursos não geridos, deve certificar-se de chamar o seu IDisposable.Dispose método quando terminar de o usar. (Alguns tipos também implementam um Close método que é idêntico em função a um Dispose método.) Para mais informações, consulte o tópico Usar Objetos que Implementam IDisposável .
Se criou um tipo que utiliza recursos não geridos, certifique-se de que implementou o padrão Dispose e, se necessário, forneceu um finalizador. Para mais informações, consulte Implementar um método Dispose e Object.Finalize.
Está a tentar criar um grande array num processo de 64 bits
Por defeito, o tempo de execução da linguagem comum no .NET Framework não permite objetos únicos cujo tamanho exceda 2GB. Para sobrescrever este padrão, pode usar a <configuração gcAllowVeryLargeObjects> para ativar arrays cujo tamanho total exceda 2 GB. No .NET Core, o suporte para arrays superiores a 2 GB está ativado por defeito.
Está a trabalhar com conjuntos muito grandes de dados (como arrays, coleções ou conjuntos de dados de bases de dados) na memória.
Quando as estruturas de dados ou conjuntos de dados que residem na memória se tornam tão grandes que o tempo de execução da linguagem comum não consegue alocar memória contígua suficiente para elas, resulta uma OutOfMemoryException exceção.
Para evitar exceções OutOfMemoryException , deve modificar a sua aplicação para que menos dados residam na memória, ou os dados são divididos em segmentos que exigem alocações de memória menores. Por exemplo:
Se estiver a recuperar todos os dados de uma base de dados e depois a filtrá-los na sua aplicação para minimizar viagens ao servidor, deve modificar as suas consultas para devolver apenas o subconjunto de dados que a sua aplicação precisa. Quando se trabalha com tabelas grandes, múltiplas consultas são quase sempre mais eficientes do que recuperar todos os dados de uma única tabela e depois manipulá-los.
Se estiver a executar consultas que os utilizadores criam dinamicamente, deve garantir que o número de registos devolvidos pela consulta é limitado.
Se estiver a usar grandes arrays ou outros objetos de coleção cujo tamanho resulte numa OutOfMemoryException exceção, deve modificar a sua aplicação para trabalhar os dados em subconjuntos em vez de trabalhar com todos de uma vez.
O exemplo seguinte obtém um array que consiste em 200 milhões de valores de ponto flutuante e depois calcula a sua média. A saída do exemplo mostra que, como o exemplo armazena todo o array na memória antes de calcular a média, um OutOfMemoryException é lançado.
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.
O exemplo seguinte elimina a OutOfMemoryException exceção ao processar os dados recebidos sem armazenar todo o conjunto de dados na memória, serializando os dados para um ficheiro se necessário para permitir processamento adicional (estas linhas são comentadas no exemplo, pois neste caso produzem um ficheiro com tamanho superior a 1GB), e retornando a média calculada e o número de casos à rotina de chamada.
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
Estás a concatenar repetidamente cadeias grandes.
Como as cadeias são imutáveis, cada operação de concatenação cria uma nova cadeia. O impacto para cadeias pequenas, ou para um pequeno número de operações de concatenação, é negligenciável. Mas para cadeias grandes ou um número muito elevado de operações de concatenação, a concatenação de cadeias pode levar a um grande número de alocações de memória e fragmentação de memória, baixo desempenho e possivelmente OutOfMemoryException exceções.
Ao concatenar cadeias grandes ou realizar um grande número de operações de concatenação, deve usar a StringBuilder classe em vez da String classe. Quando terminares de manipular a cadeia, converte a StringBuilder instância numa cadeia chamando o StringBuilder.ToString método.
Fixas um grande número de objetos na memória.
Fixar um grande número de objetos na memória durante longos períodos pode dificultar que o coletor de lixo aloque blocos contíguos de memória. Se fixou um grande número de objetos na memória, por exemplo usando a fixed instrução em C# ou chamando o GCHandle.Alloc(Object, GCHandleType) método com um tipo de handle , GCHandleType.Pinnedpode fazer o seguinte para abordar a OutOfMemoryException exceção.
Avaliar se cada objeto realmente precisa de ser fixado,
Certifique-se de que cada objeto é desimobilizado o mais rapidamente possível.
Certifique-se de que cada chamada ao GCHandle.Alloc(Object, GCHandleType) método para fixar memória tem uma chamada correspondente ao GCHandle.Free método para desfixar essa memória.
As seguintes instruções Microsoft intermédias (MSIL) lançam uma exceção OutOfMemoryException:
Construtores
| Name | Description |
|---|---|
| OutOfMemoryException() |
Inicializa uma nova instância da OutOfMemoryException classe. |
| OutOfMemoryException(SerializationInfo, StreamingContext) |
Inicializa uma nova instância da OutOfMemoryException classe com dados serializados. |
| OutOfMemoryException(String, Exception) |
Inicializa uma nova instância da OutOfMemoryException classe com uma mensagem de erro especificada e uma referência à exceção interna que é a causa dessa exceção. |
| OutOfMemoryException(String) |
Inicializa uma nova instância da OutOfMemoryException classe com uma mensagem de erro especificada. |
Propriedades
| Name | Description |
|---|---|
| Data |
Obtém uma coleção de pares chave/valor que fornecem informação adicional definida pelo utilizador sobre a exceção. (Herdado de Exception) |
| HelpLink |
Obtém ou define um link para o ficheiro de ajuda associado a esta exceção. (Herdado de Exception) |
| HResult |
Recebe ou define HRESULT, um valor numérico codificado atribuído a uma exceção específica. (Herdado de Exception) |
| InnerException |
Obtém a Exception instância que causou a exceção atual. (Herdado de Exception) |
| Message |
Recebe uma mensagem que descreve a exceção atual. (Herdado de Exception) |
| Source |
Obtém ou define o nome do aplicativo ou o objeto que causa o erro. (Herdado de Exception) |
| StackTrace |
Obtém uma representação string dos frames imediatos na stack de chamadas. (Herdado de Exception) |
| TargetSite |
Obtém o método que lança a exceção atual. (Herdado de Exception) |
Métodos
| Name | Description |
|---|---|
| Equals(Object) |
Determina se o objeto especificado é igual ao objeto atual. (Herdado de Object) |
| GetBaseException() |
Quando sobrescrito numa classe derivada, devolve o Exception que é a causa raiz de uma ou mais exceções subsequentes. (Herdado de Exception) |
| GetHashCode() |
Serve como função de hash predefinida. (Herdado de Object) |
| GetObjectData(SerializationInfo, StreamingContext) |
Quando sobreposto numa classe derivada, define a SerializationInfo informação com sobre a exceção. (Herdado de Exception) |
| GetType() |
Obtém o tipo de execução da instância atual. (Herdado de Exception) |
| MemberwiseClone() |
Cria uma cópia superficial do atual Object. (Herdado de Object) |
| ToString() |
Cria e devolve uma representação string da exceção atual. (Herdado de Exception) |
evento
| Name | Description |
|---|---|
| SerializeObjectState |
Ocorre quando uma exceção é serializada para criar um objeto de estado de exceção que contém dados serializados sobre a exceção. (Herdado de Exception) |