OutOfMemoryException OutOfMemoryException OutOfMemoryException OutOfMemoryException Class

定义

没有足够的内存继续执行程序时引发的异常。The exception that is thrown when there is not enough memory to continue the execution of a program.

public ref class OutOfMemoryException : SystemException
[System.Runtime.InteropServices.ComVisible(true)]
[System.Serializable]
public class OutOfMemoryException : SystemException
type OutOfMemoryException = class
    inherit SystemException
Public Class OutOfMemoryException
Inherits SystemException
继承
OutOfMemoryExceptionOutOfMemoryExceptionOutOfMemoryExceptionOutOfMemoryException
派生
属性

注解

OutOfMemoryException 使用 HRESULT COR_E_OUTOFMEMORY,其中包含已用完 0x8007000E 的值。OutOfMemoryException uses the HRESULT COR_E_OUTOFMEMORY, which has the value 0x8007000E.

有关实例的初始属性值的列表OutOfMemoryException,请参阅OutOfMemoryException构造函数。For a list of initial property values for an instance of OutOfMemoryException, see the OutOfMemoryException constructors.

备注

值继承Data属性始终为nullThe value of the inherited Data property is always null.

OutOfMemoryException异常有两个主要原因:An OutOfMemoryException exception has two major causes:

  • 尝试展开StringBuilder对象定义的长度超出其StringBuilder.MaxCapacity属性。You are attempting to expand a StringBuilder object beyond the length defined by its StringBuilder.MaxCapacity property.

  • 公共语言运行时无法分配连续内存不足,无法成功执行操作。The common language runtime cannot allocate enough contiguous memory to successfully perform an operation. 可以由任何需要的内存分配的属性赋值或方法调用引发此异常。This exception can be thrown by any property assignment or method call that requires a memory allocation. 有关详细信息的原因OutOfMemoryException异常,请参阅"内存不足"不是指物理内存For more information on the cause of the OutOfMemoryException exception, see "Out of Memory" Does Not Refer to Physical Memory.

    这种类型的OutOfMemoryException异常表示发生灾难性故障。This type of OutOfMemoryException exception represents a catastrophic failure. 如果您选择要处理的异常,应包括catch块调用Environment.FailFast方法来终止您的应用程序并向系统事件日志中,添加一个条目,如以下示例所示。If you choose to handle the exception, you should include a catch block that calls the Environment.FailFast method to terminate your app and add an entry to the system event log, as the following example does.

    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...
    
    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...
    

某些在其下引发异常,并且可用于消除它的操作包括以下条件:Some of the conditions under which the exception is thrown and the actions you can take to eliminate it include the following:

正在调用StringBuilder.Insert方法。You are calling the StringBuilder.Insert method.

尝试增加的长度StringBuilder对象指定的大小超出其StringBuilder.MaxCapacity属性。You are attempting to increase the length of a StringBuilder object beyond the size specified by its StringBuilder.MaxCapacity property. 下面的示例阐释OutOfMemoryException通过调用引发异常StringBuilder.Insert(Int32, String, Int32)方法时此示例尝试将导致对象的字符串插入Length属性超过其最大容量。The following example illustrates the OutOfMemoryException exception thrown by a call to the StringBuilder.Insert(Int32, String, Int32) method when the example tries to insert a string that would cause the object's Length property to exceed its maximum capacity.

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.
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.

您可以执行以下操作来解决此错误:You can do either of the following to address the error:

您的应用程序以 32 位进程形式运行。Your app runs as a 32-bit process.

32 位进程可以分配最多 2 GB 的 32 位系统上的虚拟用户模式内存,4 GB 的 64 位系统上的用户模式虚拟内存。32-bit processes can allocate a maximum of 2GB of virtual user-mode memory on 32-bit systems, and 4GB of virtual user-mode memory on 64-bit systems. 这会使公共语言运行时根据需要分配大量的分配足够的连续内存更困难。This can make it more difficult for the common language runtime to allocate sufficient contiguous memory when a large allocation is needed. 与此相反,64 位进程可以分配多达 8 TB 的虚拟内存。In contrast, 64-bit processes can allocate up to 8TB of virtual memory. 若要解决此异常,请重新编译您的应用程序以面向 64 位平台。To address this exception, recompile your app to target a 64-bit platform. 针对 Visual Studio 中的特定平台的信息,请参阅如何:将项目配置为面向平台For information on targeting specific platforms in Visual Studio, see How to: Configure Projects to Target Platforms.

应用正在泄露非托管的资源Your app is leaking unmanaged resources

虽然垃圾回收器可以释放内存分配给托管类型,它不会管理分配给非托管资源,如操作系统处理 (包括文件、 内存映射文件、 管道、 注册表项和等待句柄的句柄) 的内存和直接由 Windows API 调用或对内存分配函数的调用如分配内存块mallocAlthough the garbage collector is able to free memory allocated to managed types, it does not manage memory allocated to unmanaged resources such as operating system handles (including handles to files, memory-mapped files, pipes, registry keys, and wait handles) and memory blocks allocated directly by Windows API calls or by calls to memory allocation functions such as malloc. 使用非托管的资源的类型可实现IDisposable接口。Types that consume unmanaged resources implement the IDisposable interface.

如果您正在使用使用非托管的资源的类型,您应确保调用其IDisposable.Dispose方法使用它完成。If you are consuming a type that uses unmanaged resources, you should be sure to call its IDisposable.Dispose method when you have finished using it. (某些类型还实现Close方法在功能上与相同Dispose方法。)有关详细信息,请参阅使用对象,实现 IDisposable主题。(Some types also implement a Close method that is identical in function to a Dispose method.) For more information, see the Using Objects That Implement IDisposable topic.

如果已创建使用非托管的资源的类型,请确保你已实现 Dispose 模式并,如有必要,提供终结器。If you have created a type that uses unmanaged resources, make sure that you have implemented the Dispose pattern and, if necessary, supplied a finalizer. 有关详细信息,请参阅实现 Dispose 方法Object.FinalizeFor more information, see Implementing a Dispose method and Object.Finalize.

您尝试在 64 位进程中创建一个大型数组You are attempting to create a large array in a 64-bit process

默认情况下,在.NET Framework 公共语言运行时不允许其大小超过 2 GB 的单个对象。By default, the common language runtime in .NET Framework does not allow single objects whose size exceeds 2GB. 若要覆盖此默认设置,可以使用 <gcAllowVeryLargeObjects >配置文件设置以启用总大小超过 2 GB 的数组。To override this default, you can use the <gcAllowVeryLargeObjects> configuration file setting to enable arrays whose total size exceeds 2 GB. 在.NET Core 上支持大于 2 GB 默认情况下启用的数组。On .NET Core, support for arrays of greater than 2 GB is enabled by default.

你正在使用非常大 (如数组、 集合或数据库的数据集) 的数据集在内存中。You are working with very large sets of data (such as arrays, collections, or database data sets) in memory.

当数据结构或驻留在内存中的数据集变得太大,公共语言运行时无法为它们分配连续内存不足时OutOfMemoryException异常结果。When data structures or data sets that reside in memory become so large that the common language runtime is unable to allocate enough contiguous memory for them, an OutOfMemoryException exception results.

若要防止OutOfMemoryException异常,则必须修改应用程序,以便更少的数据驻留在内存中,或将数据划分成需要的较小的内存分配的段。To prevent the OutOfMemoryException exceptions, you must modify your application so that less data is resident in memory, or the data is divided into segments that require smaller memory allocations. 例如:For example:

  • 如果是从数据库检索的所有数据,然后对其进行筛选以最大程度减少往返服务器应用程序中,您应修改查询以返回仅应用所需的数据子集。If you are retrieving all of the data from a database and then filtering it in your app to minimize trips to the server, you should modify your queries to return only the subset of data that your app needs. 使用大型表时,多个查询时,几乎总是的详细信息比检索所有单个表中的数据,然后对其进行处理的效率高。When working with large tables, multiple queries are almost always more efficient than retrieving all of the data in a single table and then manipulating it.

  • 如果在执行用户动态创建的查询,应确保由查询返回的记录数会受到限制。If you are executing queries that users create dynamically, you should ensure that the number of records returned by the query is limited.

  • 如果使用的大型数组或对象的其他集合中的其大小结果OutOfMemoryException异常,则应修改应用程序能够将数据子集而不是一次性全部使用它。If you are using large arrays or other collection objects whose size results in an OutOfMemoryException exception, you should modify your application to work the data in subsets rather than to work with it all at once.

以下示例将获取一个数组,其中包括 200 万个浮点值,然后计算其平均值。The following example gets a array that consists of 200 million floating-point values and then calculates their mean. 该示例的输出显示,因为该示例在内存中存储整个数组,它会计算平均值之前,OutOfMemoryException引发。The output from the example shows that, because the example stores the entire array in memory before it calculates the mean, an OutOfMemoryException is thrown.

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.
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.

下面的示例可消除OutOfMemoryException由处理传入的数据,而不是将整个数据集存储在内存中,序列化到文件数据,如有必要以允许进一步处理 (这些行中注释掉示例中,异常由于这种情况下它们生成一个文件,其大小是大于 1 GB),并将计算的平均值和事例数返回到调用例程。The following example eliminates the OutOfMemoryException exception by processing the incoming data without storing the entire data set in memory, serializing the data to a file if necessary to permit further processing (these lines are commented out in the example, since in this case they produce a file whose size is greater than 1GB), and returning the calculated mean and the number of cases to the calling routine.

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
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

重复连接长字符串。You are repeatedly concatenating large strings.

由于字符串是不可变,每个字符串串联操作将创建一个新字符串。Because strings are immutable, each string concatenation operation creates a new string. 对于小字符串,或对于串联操作中,较少数量的影响可以忽略不计。The impact for small strings, or for a small number of concatenation operations, is negligible. 但对于大型字符串或非常大量的串联操作中,字符串串联可能会导致大量的内存分配和内存碎片,性能不佳,并可能OutOfMemoryException异常。But for large strings or a very large number of concatenation operations, string concatenation can lead to a large number of memory allocations and memory fragmentation, poor performance, and possibly OutOfMemoryException exceptions.

当连接长字符串,或执行大量的串联操作中,您应使用StringBuilder类而不是String类。When concatenating large strings or performing a large number of concatenation operations, you should use the StringBuilder class instead of the String class. 完成操作字符串后,将转换StringBuilder实例与通过调用字符串StringBuilder.ToString方法。When you have finished manipulating the string, convert the StringBuilder instance to a string by calling the StringBuilder.ToString method.

将大量对象固定在内存中。You pin a large number of objects in memory.

很长一段固定内存中的大量对象可以使难以垃圾回收器分配的内存的连续块。Pinning a large number of objects in memory for long periods can make it difficult for the garbage collector to allocate contiguous blocks of memory. 如果已将固定大量对象在内存中,例如通过使用fixed语句在 C# 或通过调用GCHandle.Alloc(Object, GCHandleType)方法的句柄类型替换GCHandleType.Pinned,您可以执行以下操作为地址OutOfMemoryException异常。If you've pinned a large number of objects in memory, for example by using the fixed statement in C# or by calling the GCHandle.Alloc(Object, GCHandleType) method with a handle type of GCHandleType.Pinned, you can do the following to address the OutOfMemoryException exception.

  • 评估是否真的需要固定,每个对象Evaluate whether each object really needs to be pinned,

  • 请确保每个对象已取消固定越早越好。Ensure that each object is unpinned as soon as possible.

  • 请确保每个调用到GCHandle.Alloc(Object, GCHandleType)pin 内存的方法具有相应地调用GCHandle.Free方法来取消固定的内存。Make sure that each call to the GCHandle.Alloc(Object, GCHandleType) method to pin memory has a corresponding call to the GCHandle.Free method to unpin that memory.

以下 Microsoft 中间 (MSIL) 指令引发OutOfMemoryException异常:The following Microsoft intermediate (MSIL) instructions throw an OutOfMemoryException exception:

构造函数

OutOfMemoryException() OutOfMemoryException() OutOfMemoryException() OutOfMemoryException()

初始化 OutOfMemoryException 类的新实例。Initializes a new instance of the OutOfMemoryException class.

OutOfMemoryException(SerializationInfo, StreamingContext) OutOfMemoryException(SerializationInfo, StreamingContext) OutOfMemoryException(SerializationInfo, StreamingContext) OutOfMemoryException(SerializationInfo, StreamingContext)

用序列化数据初始化 OutOfMemoryException 类的新实例。Initializes a new instance of the OutOfMemoryException class with serialized data.

OutOfMemoryException(String) OutOfMemoryException(String) OutOfMemoryException(String) OutOfMemoryException(String)

用指定的错误消息初始化 OutOfMemoryException 类的新实例。Initializes a new instance of the OutOfMemoryException class with a specified error message.

OutOfMemoryException(String, Exception) OutOfMemoryException(String, Exception) OutOfMemoryException(String, Exception) OutOfMemoryException(String, Exception)

使用指定的错误消息和对作为此异常原因的内部异常的引用来初始化 OutOfMemoryException 类的新实例。Initializes a new instance of the OutOfMemoryException class with a specified error message and a reference to the inner exception that is the cause of this exception.

属性

Data Data Data Data

获取提供有关异常的其他用户定义信息的键/值对集合。Gets a collection of key/value pairs that provide additional user-defined information about the exception.

(Inherited from Exception)
HelpLink HelpLink HelpLink HelpLink

获取或设置指向与此异常关联的帮助文件链接。Gets or sets a link to the help file associated with this exception.

(Inherited from Exception)
HResult HResult HResult HResult

获取或设置 HRESULT(一个分配给特定异常的编码数字值)。Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception.

(Inherited from Exception)
InnerException InnerException InnerException InnerException

获取导致当前异常的 Exception 实例。Gets the Exception instance that caused the current exception.

(Inherited from Exception)
Message Message Message Message

获取描述当前异常的消息。Gets a message that describes the current exception.

(Inherited from Exception)
Source Source Source Source

获取或设置导致错误的应用程序或对象的名称。Gets or sets the name of the application or the object that causes the error.

(Inherited from Exception)
StackTrace StackTrace StackTrace StackTrace

获取调用堆栈上的即时框架字符串表示形式。Gets a string representation of the immediate frames on the call stack.

(Inherited from Exception)
TargetSite TargetSite TargetSite TargetSite

获取引发当前异常的方法。Gets the method that throws the current exception.

(Inherited from Exception)

方法

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

确定指定的对象是否等于当前对象。Determines whether the specified object is equal to the current object.

(Inherited from Object)
GetBaseException() GetBaseException() GetBaseException() GetBaseException()

当在派生类中重写时,返回 Exception,它是一个或多个并发的异常的根源。When overridden in a derived class, returns the Exception that is the root cause of one or more subsequent exceptions.

(Inherited from Exception)
GetHashCode() GetHashCode() GetHashCode() GetHashCode()

作为默认哈希函数。Serves as the default hash function.

(Inherited from Object)
GetObjectData(SerializationInfo, StreamingContext) GetObjectData(SerializationInfo, StreamingContext) GetObjectData(SerializationInfo, StreamingContext) GetObjectData(SerializationInfo, StreamingContext)

当在派生类中重写时,用关于异常的信息设置 SerializationInfoWhen overridden in a derived class, sets the SerializationInfo with information about the exception.

(Inherited from Exception)
GetType() GetType() GetType() GetType()

获取当前实例的运行时类型。Gets the runtime type of the current instance.

(Inherited from Exception)
MemberwiseClone() MemberwiseClone() MemberwiseClone() MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(Inherited from Object)
ToString() ToString() ToString() ToString()

创建并返回当前异常的字符串表示形式。Creates and returns a string representation of the current exception.

(Inherited from Exception)

事件

SerializeObjectState SerializeObjectState SerializeObjectState SerializeObjectState

当异常被序列化用来创建包含有关该异常的徐列出数据的异常状态对象时会出现该问题。Occurs when an exception is serialized to create an exception state object that contains serialized data about the exception.

(Inherited from Exception)

适用于

另请参阅