OutOfMemoryException クラス

定義

プログラムの実行を継続するためのメモリが不足している場合にスローされる例外。

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
継承
OutOfMemoryException
継承
OutOfMemoryException
派生
属性

注釈

OutOfMemoryException では、 COR_E_OUTOFMEMORY 値が0x8007000E の HRESULT が使用されます。

インスタンスの初期プロパティ値の一覧についてはOutOfMemoryExceptionを参照してください、OutOfMemoryExceptionコンス トラクター。

注意

継承されたプロパティの値 Data は常に null です。

OutOfMemoryException例外には、次の2つの主要な原因があります。

  • StringBuilderプロパティによって定義された長さを超えてオブジェクトを展開しようとしてい StringBuilder.MaxCapacity ます。

  • 共通言語ランタイムは、操作を正常に実行するために十分な連続メモリを割り当てることができません。 この例外は、メモリの割り当てを必要とするプロパティの割り当てまたはメソッドの呼び出しによってスローされる場合があります。 例外の原因の詳細につい OutOfMemoryException ては、ブログの 「メモリ不足」によって物理メモリが参照されていないことを確認してください。

    この種類の OutOfMemoryException 例外は、致命的なエラーを表します。 例外を処理する場合は、 catch Environment.FailFast 次の例に示すように、メソッドを呼び出してアプリを終了し、システムイベントログにエントリを追加するブロックを含める必要があります。

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

例外がスローされるいくつかの条件と、それを排除するために実行できるアクションを次に示します。

メソッドを呼び出してい StringBuilder.Insert ます。

StringBuilderプロパティで指定されたサイズを超えてオブジェクトの長さを増やしようとしてい StringBuilder.MaxCapacity ます。 次の例は、 OutOfMemoryException メソッドの呼び出しによってスローされる例外を示してい StringBuilder.Insert(Int32, String, Int32) ます。この例では、オブジェクトの Length プロパティが最大容量を超える可能性のある文字列を挿入しようとしています。

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.

エラーを解決するには、次のいずれかを実行します。

アプリは、32ビットプロセスとして実行されます。

32ビットプロセスでは、32ビットシステムでは最大 2 GB の仮想ユーザーモードメモリ、64ビットシステムでは 4 GB の仮想ユーザーモードメモリを割り当てることができます。 これにより、大量の割り当てが必要な場合に、共通言語ランタイムが十分な連続メモリを割り当てることが困難になる可能性があります。 これに対し、64ビットプロセスでは最大 8 TB の仮想メモリを割り当てることができます。 この例外に対処するには、64ビットプラットフォームを対象とするようにアプリを再コンパイルします。 Visual Studio で特定のプラットフォームを対象にする方法の詳細については、「方法: プロジェクトを構成してターゲットプラットフォームを設定する」を参照してください。

アプリがアンマネージリソースをリークしています

ガベージコレクターは、マネージ型に割り当てられたメモリを解放できますが、オペレーティングシステムハンドル (ファイルへのハンドル、メモリマップトファイル、パイプ、レジストリキー、待機ハンドルなど) および Windows API 呼び出しによって直接割り当てられたメモリブロックや、などのメモリ割り当て関数への呼び出しによって割り当てられたメモリブロックは管理しません malloc 。 アンマネージリソースを使用する型は、インターフェイスを実装し IDisposable ます。

アンマネージリソースを使用する型を使用している場合は、そのメソッドの使用が完了したら、そのメソッドを呼び出す必要があり IDisposable.Dispose ます。 (一部の型 Close では、関数とメソッドの同一メソッドも実装されて Dispose います)。詳細については、「 IDisposable を実装するオブジェクトの使用 」を参照してください。

アンマネージリソースを使用する型を作成した場合は、Dispose パターンを実装していることを確認し、必要に応じてファイナライザーを指定してください。 詳細については、「 Dispose メソッドの実装 」および「」を参照してください Object.Finalize

64ビットプロセスで大きな配列を作成しようとしています

既定では .NET Framework の共通言語ランタイムでは、サイズが 2 gb を超える単一オブジェクトは許可されません。 この既定値をオーバーライドするには、 <gcAllowVeryLargeObjects> 構成ファイルの設定を使用して、合計サイズが 2 GB を超える配列を有効にします。 .NET Core では、2 GB を超える配列のサポートは既定で有効になっています。

メモリ内で非常に大きなデータセット (配列、コレクション、データベースデータセットなど) を使用しています。

メモリに格納されているデータ構造またはデータセットが非常に大きくなり、共通言語ランタイムがそれに対して十分な連続メモリを割り当てることができない場合、例外が発生 OutOfMemoryException します。

例外を回避するには OutOfMemoryException 、メモリに格納されるデータの量が少なくなるようにアプリケーションを変更するか、メモリの割り当てを小さくする必要があるセグメントにデータを分割します。 次に例を示します。

  • データベースからすべてのデータを取得し、それをアプリでフィルター処理してサーバーへのトリップを最小限に抑える場合は、アプリに必要なデータのサブセットのみを返すようにクエリを変更する必要があります。 大きなテーブルを扱う場合、1つのテーブル内のすべてのデータを取得して操作するよりも、ほとんどの場合、複数のクエリの方が効率的です。

  • ユーザーが動的に作成するクエリを実行する場合は、クエリによって返されるレコードの数が制限されていることを確認する必要があります。

  • サイズが大きい配列やその他のコレクションオブジェクトを使用していて、そのサイズが例外になる場合は、同時に OutOfMemoryException 処理するのではなく、サブセット内のデータを処理するようにアプリケーションを変更する必要があります。

次の例では、2億の浮動小数点値で構成される配列を取得し、その平均を計算します。 この例の出力は、平均値を計算する前に配列全体がメモリに格納されるため、がスローされることを示してい 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.
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 を超えるファイルを生成し、計算された平均とケースの数を呼び出し

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

大きな文字列を繰り返し連結しています。

文字列は不変であるため、各文字列連結操作で新しい文字列が作成されます。 小さな文字列への影響、または少数の連結操作に対する影響は、ごくわずかです。 ただし、大きな文字列または非常に多くの連結操作の場合、文字列の連結によって、大量のメモリ割り当てやメモリの断片化、パフォーマンスの低下、および場合によっては例外が発生する可能性が OutOfMemoryException あります。

大きな文字列を連結する場合、または多数の連結演算を実行する場合は、クラスの代わりにクラスを使用する必要があり StringBuilder String ます。 文字列の操作が完了したら、メソッドを StringBuilder 呼び出して、インスタンスを文字列に変換し StringBuilder.ToString ます。

メモリ内に多数のオブジェクトをピン留めします。

長時間にわたって多数のオブジェクトをメモリに固定すると、ガベージコレクターが連続したメモリブロックを割り当てることが困難になる可能性があります。 たとえば、C# のステートメントを使用するか、のハンドル型を使用してメソッドを呼び出すことによって、メモリ内に多数のオブジェクトをピン留めした場合は、 fixed GCHandle.Alloc(Object, GCHandleType) GCHandleType.Pinned 次のようにして例外に対処でき OutOfMemoryException ます。

  • 各オブジェクトを実際に固定する必要があるかどうかを評価します。

  • 各オブジェクトの固定ができるだけ早く解除されていることを確認します。

  • メモリをピン留めするためのメソッドの各呼び出しに、対応するメソッドへの呼び出しがあることを確認して、 GCHandle.Alloc(Object, GCHandleType) GCHandle.Free そのメモリを固定解除します。

次の Microsoft 中間 (MSIL) 命令は例外をスローし OutOfMemoryException ます。

コンストラクター

OutOfMemoryException()

OutOfMemoryException クラスの新しいインスタンスを初期化します。

OutOfMemoryException(SerializationInfo, StreamingContext)

シリアル化したデータを使用して、OutOfMemoryException クラスの新しいインスタンスを初期化します。

OutOfMemoryException(String)

指定したエラー メッセージを使用して、OutOfMemoryException クラスの新しいインスタンスを初期化します。

OutOfMemoryException(String, Exception)

指定したエラー メッセージおよびこの例外の原因となった内部例外への参照を使用して、OutOfMemoryException クラスの新しいインスタンスを初期化します。

プロパティ

Data

例外に関する追加のユーザー定義情報を提供する、キーと値のペアのコレクションを取得します。

(継承元 Exception)
HelpLink

この例外に関連付けられているヘルプ ファイルへのリンクを取得または設定します。

(継承元 Exception)
HResult

特定の例外に割り当てられているコード化数値である HRESULT を取得または設定します。

(継承元 Exception)
InnerException

現在の例外の原因となる Exception インスタンスを取得します。

(継承元 Exception)
Message

現在の例外を説明するメッセージを取得します。

(継承元 Exception)
Source

エラーの原因となるアプリケーションまたはオブジェクトの名前を取得または設定します。

(継承元 Exception)
StackTrace

呼び出し履歴で直前のフレームの文字列形式を取得します。

(継承元 Exception)
TargetSite

現在の例外がスローされたメソッドを取得します。

(継承元 Exception)

メソッド

Equals(Object)

指定されたオブジェクトが現在のオブジェクトと等しいかどうかを判断します。

(継承元 Object)
GetBaseException()

派生クラスでオーバーライドされた場合、それ以後に発生する 1 つ以上の例外の根本原因である Exception を返します。

(継承元 Exception)
GetHashCode()

既定のハッシュ関数として機能します。

(継承元 Object)
GetObjectData(SerializationInfo, StreamingContext)

派生クラスでオーバーライドされた場合は、その例外に関する情報を使用して SerializationInfo を設定します。

(継承元 Exception)
GetType()

現在のインスタンスのランタイム型を取得します。

(継承元 Exception)
MemberwiseClone()

現在の Object の簡易コピーを作成します。

(継承元 Object)
ToString()

現在の例外の文字列形式を作成して返します。

(継承元 Exception)

イベント

SerializeObjectState
互換性のために残されています。

例外がシリアル化され、例外に関するシリアル化されたデータを含む例外状態オブジェクトが作成されたときに発生します。

(継承元 Exception)

適用対象

こちらもご覧ください