ガベージ コレクションとパフォーマンスGarbage Collection and Performance

ここでは、ガベージ コレクションおよびメモリ使用に関連する問題について説明します。This topic describes issues related to garbage collection and memory usage. マネージド ヒープに関する問題について取り上げ、ガベージ コレクションによるアプリケーションに対する影響を最小限に抑える方法を説明します。It addresses issues that pertain to the managed heap and explains how to minimize the effect of garbage collection on your applications. 問題を調査するために使用できる手順のリンクを問題ごとに示してあります。Each issue has links to procedures that you can use to investigate problems.

このトピックは、次のセクションで構成されています。This topic contains the following sections:

パフォーマンス分析ツールPerformance Analysis Tools

以下のセクションでは、メモリ使用とガベージ コレクションに関する問題を調査するために使用できるツールについて説明します。The following sections describe the tools that are available for investigating memory usage and garbage collection issues. このトピックの後半で説明する手順では、これらのツールを使用します。The procedures provided later in this topic refer to these tools.

メモリ パフォーマンス カウンターMemory Performance Counters

パフォーマンス カウンターを使用してパフォーマンス データを収集できます。You can use performance counters to gather performance data. 手順については、「ランタイム プロファイリング」を参照してください。For instructions, see Runtime Profiling. ガベージ コレクターに関する情報は、.NET CLR Memory カテゴリのパフォーマンス カウンターから提供されます。詳細については、「.NET Framework のパフォーマンス カウンター」を参照してください。The .NET CLR Memory category of performance counters, as described in Performance Counters in the .NET Framework, provides information about the garbage collector.

SOS キーを使ったデバッグDebugging with SOS

Windows デバッガー (WinDbg) を使用して、マネージド ヒープのオブジェクトを検査できます。You can use the Windows Debugger (WinDbg) to inspect objects on the managed heap.

WinDbg をインストールするには、「Download Debugging Tools for Windows」 (Windows 用デバッグ ツールのダウンロード) ページから Windows 用デバッグ ツールをインストールします。To install WinDbg, install Debugging Tools for Windows from the Download Debugging Tools for Windows page.

ガベージ コレクション ETW イベントGarbage Collection ETW Events

Windows イベント トレーシング (ETW) は、.NET Framework のプロファイリングとデバッグのサポートを補足するトレース システムです。Event tracing for Windows (ETW) is a tracing system that supplements the profiling and debugging support provided by the .NET Framework. .NET Framework 4 以降では、ガベージ コレクション ETW イベントにより、統計的な観点からマネージド ヒープを分析するために役立つ情報が得られるようになりました。Starting with the .NET Framework 4, garbage collection ETW events capture useful information for analyzing the managed heap from a statistical point of view. たとえば、ガベージ コレクションの発生前に発生する GCStart_V1 イベントでは、次の情報が提供されます。For example, the GCStart_V1 event, which is raised when a garbage collection is about to occur, provides the following information:

  • 収集されるオブジェクトのジェネレーションWhich generation of objects is being collected.

  • ガベージ コレクションが発生した理由What triggered the garbage collection.

  • ガベージ コレクションの種類 (同時実行または非同時実行)Type of garbage collection (concurrent or not concurrent).

ETW イベント ログは効率的であり、ガベージ コレクションに関連するパフォーマンスの問題がマスクされることはありません。ETW event logging is efficient and will not mask any performance problems associated with garbage collection. ETW イベントと組み合わせてプロセス独自のイベントを提供できます。A process can provide its own events in conjunction with ETW events. ログを記録すると、アプリケーションのイベントとガベージ コレクションのイベントの両方を相互に関連付けて、ヒープの問題がいつどのようにして発生するかを特定できます。When logged, both the application's events and the garbage collection events can be correlated to determine how and when heap problems occur. たとえば、サーバー アプリケーションでは、クライアント要求の開始時と終了時にイベントを提供することができます。For example, a server application could provide events at the start and end of a client request.

プロファイル APIThe Profiling API

共通言語ランタイム (CLR) のプロファイル インターフェイスは、ガベージ コレクションの影響を受けたオブジェクトに関する詳細な情報を提供します。The common language runtime (CLR) profiling interfaces provide detailed information about the objects that were affected during garbage collection. プロファイラーでは、ガベージ コレクションの開始時と終了時に通知を受け取り、A profiler can be notified when a garbage collection starts and ends. 各ジェネレーションにおけるオブジェクトの識別情報など、マネージド ヒープのオブジェクトに関するレポートを提供することができます。It can provide reports about the objects on the managed heap, including an identification of objects in each generation. 詳細については、「プロファイルの概要」を参照してください。For more information, see Profiling Overview.

プロファイラーでは包括的な情報を提供できますが、Profilers can provide comprehensive information. 複雑なプロファイラーを使用すると、アプリケーションの動作が変更される可能性があります。However, complex profilers can potentially modify an application's behavior.

アプリケーション ドメインのリソース監視Application Domain Resource Monitoring

.NET Framework 4 以降では、アプリケーション ドメインのリソース監視 (ARM) によって、ホストで CPU とメモリのアプリケーション ドメインによる使用状況を監視できるようになります。Starting with the .NET Framework 4, Application domain resource monitoring (ARM) enables hosts to monitor CPU and memory usage by application domain. 詳細については、「アプリケーション ドメインのリソース監視」を参照してください。For more information, see Application Domain Resource Monitoring.

ページのトップへBack to top

パフォーマンスに関する問題のトラブルシューティングTroubleshooting Performance Issues

最初に、本当にガベージ コレクションの問題なのかどうかを確認しますThe first step is to determine whether the issue is actually garbage collection. ガベージ コレクションの問題であることがわかったら、次の一覧から問題を選択してトラブルシューティングを行います。If you determine that it is, select from the following list to troubleshoot the problem.

問題: メモリ不足の例外がスローされるIssue: An Out-of-Memory Exception Is Thrown

OutOfMemoryException マネージド例外がスローされる正当な状況としては、次の 2 つがあります。There are two legitimate cases for a managed OutOfMemoryException to be thrown:

  • 仮想メモリが不足している。Running out of virtual memory.

    ガベージ コレクターは、サイズがあらかじめ決められたセグメント単位でシステムのメモリを割り当てます。The garbage collector allocates memory from the system in segments of a pre-determined size. 割り当てで追加のセグメントが必要になっとときに、プロセスの仮想メモリ空間に連続する空きブロックが残っていなければ、マネージド ヒープの割り当ては失敗します。If an allocation requires an additional segment, but there is no contiguous free block left in the process's virtual memory space, the allocation for the managed heap will fail.

  • 十分な物理メモリを確保できない。Not having enough physical memory to allocate.

パフォーマンス チェックPerformance checks
メモリ不足の例外がマネージド例外かどうかを確認する。Determine whether the out-of-memory exception is managed.

予約できる仮想メモリの量を確認する。Determine how much virtual memory can be reserved.

十分な物理メモリがあるかどうかを確認する。Determine whether there is enough physical memory.

例外が正当なものでないと判断した場合は、マイクロソフト カスタマー サポート サービスにお問い合わせください。その際、次の情報をご連絡ください。If you determine that the exception is not legitimate, contact Microsoft Customer Service and Support with the following information:

  • メモリ不足のマネージド例外を含む履歴The stack with the managed out-of-memory exception.

  • 完全なメモリ ダンプFull memory dump.

  • メモリ不足の例外が正当なものでないことを証明するデータ (仮想メモリまたは物理メモリに問題がないことを示すデータなど)Data that proves that it is not a legitimate out-of-memory exception, including data that shows that virtual or physical memory is not an issue.

問題: プロセスによるメモリ使用量が多すぎるIssue: The Process Uses Too Much Memory

一般的な前提として、メモリ使用量が多すぎる場合については、Windows タスク マネージャーの [パフォーマンス] タブのメモリ使用量の表示で確認できます。A common assumption is that the memory usage display on the Performance tab of Windows Task Manager can indicate when too much memory is being used. ただし、この表示はワーキング セットに関するもので、仮想メモリの使用量に関する情報ではありません。However, that display pertains to the working set; it does not provide information about virtual memory usage.

マネージド ヒープが原因であると判断した場合は、一定の期間にわたってマネージド ヒープを測定し、パターンを確認する必要があります。If you determine that the issue is caused by the managed heap, you must measure the managed heap over time to determine any patterns.

マネージド ヒープが原因でないと判断した場合は、ネイティブ デバッグを使用する必要があります。If you determine that the problem is not caused by the managed heap, you must use native debugging.

パフォーマンス チェックPerformance checks
予約できる仮想メモリの量を確認する。Determine how much virtual memory can be reserved.

マネージド ヒープでコミットしているメモリの量を確認する。Determine how much memory the managed heap is committing.

マネージド ヒープで予約されているメモリの量を確認する。Determine how much memory the managed heap reserves.

ジェネレーション 2 の大きいオブジェクトを確認する。Determine large objects in generation 2.

オブジェクトへの参照を確認する。Determine references to objects.

問題: ガベージ コレクターによるオブジェクトの解放に時間がかかるIssue: The Garbage Collector Does Not Reclaim Objects Fast Enough

ガベージ コレクションでオブジェクトが通常どおりに解放されていないように見える場合は、それらのオブジェクトに対する強い参照がないかどうかを確認する必要があります。When it appears as if objects are not being reclaimed as expected for garbage collection, you must determine if there are any strong references to those objects.

この問題は、死んだ状態のオブジェクトを含むジェネレーションに対してガベージ コレクションが行われていない場合にも発生します。死んだ状態のオブジェクトは、そのオブジェクトのファイナライザーが実行されていないことを示します。You may also encounter this issue if there has been no garbage collection for the generation that contains a dead object, which indicates that the finalizer for the dead object has not been run. たとえば、シングルスレッド アパートメント (STA) のアプリケーションを実行している場合に、ファイナライザー キューを処理するスレッドがファイナライザーの呼び出しに失敗すると、この状態になる可能性があります。For example, this is possible when you are running a single-threaded apartment (STA) application and the thread that services the finalizer queue cannot call into it.

パフォーマンス チェックPerformance checks
オブジェクトへの参照を確認する。Check references to objects.

ファイナライザーが実行されたかどうかを確認する。Determine whether a finalizer has been run.

終了待機中のオブジェクトがないかどうかを確認する。Determine whether there are objects waiting to be finalized.

問題: マネージド ヒープが過度に断片化されるIssue: The Managed Heap Is Too fragmented

断片化レベルは、ジェネレーションに割り当てられたメモリの合計に占める空き領域の割合として計算されます。The fragmentation level is calculated as the ratio of free space over the total allocated memory for the generation. ジェネレーション 2 の場合、許容される断片化レベルは 20% 以下です。For generation 2, an acceptable level of fragmentation is no more than 20%. ジェネレーション 2 は非常に大きくなる可能性があるため、断片化の割合の方が絶対値より重要になります。Because generation 2 can get very big, the ratio of fragmentation is more important than the absolute value.

ジェネレーション 0 は、新しいオブジェクトが割り当てられるジェネレーションなので、空き領域が多くても問題はありません。Having lots of free space in generation 0 is not a problem because this is the generation where new objects are allocated.

断片化は常に大きなオブジェクト ヒープで発生します。大きなオブジェクト ヒープは圧縮されないからです。Fragmentation always occurs in the large object heap because it is not compacted. 隣接する空きオブジェクトは、大きなオブジェクトの割り当て要求を満たすために必然的に 1 つの領域にまとめられます。Free objects that are adjacent are naturally collapsed into a single space to satisfy large object allocation requests.

断片化が問題になるのは、ジェネレーション 1 とジェネレーション 2 です。Fragmentation can become a problem in generation 1 and generation 2. これらのジェネレーションで、ガベージ コレクションの終了後に大量の空き領域ある場合は、アプリケーションのオブジェクトの使用方法を変更する必要がある可能性があります。長期間のオブジェクトの有効期間を再評価することを検討してください。If these generations have a large amount of free space after a garbage collection, an application's object usage may need modification, and you should consider re-evaluating the lifetime of long-term objects.

オブジェクトの固定が過度に行われていると断片化レベルが高くなることがあります。Excessive pinning of objects can increase fragmentation. 断片化レベルが高い場合は、固定されているオブジェクトが多すぎる可能性があります。If fragmentation is high, too many objects could be pinned.

仮想メモリの断片化によってガベージ コレクターがセグメントを追加できなくなっている場合、次のような原因が考えられます。If fragmentation of virtual memory is preventing the garbage collector from adding segments, the causes could be one of the following:

  • 多数の小さなアセンブリの読み込みとアンロードが頻繁に行われている。Frequent loading and unloading of many small assemblies.

  • アンマネージ コードとの相互運用時に保持される COM オブジェクトへの参照が多すぎる。Holding too many references to COM objects when interoperating with unmanaged code.

  • 大きな一時オブジェクトが作成されているために、大きなオブジェクト ヒープでヒープ セグメントの割り当てと解放が頻繁に行われている。Creation of large transient objects, which causes the large object heap to allocate and free heap segments frequently.

    アプリケーションで CLR をホストする際には、セグメントを保持するようにガベージ コレクターに要求することができます。When hosting the CLR, an application can request that the garbage collector retain its segments. これにより、セグメント割り当ての頻度が減少します。This reduces the frequency of segment allocations. そのためには、STARTUP_FLAGS 列挙型の STARTUP_HOARD_GC_VM フラグを使用します。This is accomplished by using the STARTUP_HOARD_GC_VM flag in the STARTUP_FLAGS Enumeration.

パフォーマンス チェックPerformance checks
マネージド ヒープの空き領域の容量を確認する。Determine the amount of free space in the managed heap.

固定されたオブジェクトの数を確認する。Determine the number of pinned objects.

正当な理由もないのに断片化が発生していると思われる場合は、マイクロソフト カスタマー サポート サービスにお問い合わせください。If you think that there is no legitimate cause for the fragmentation, contact Microsoft Customer Service and Support.

問題: ガベージ コレクションの一時停止が長すぎるIssue: Garbage Collection Pauses Are Too Long

ガベージ コレクションはソフト リアルタイムで動作するため、アプリケーションはある程度の一時停止に耐えられなければなりません。Garbage collection operates in soft real time, so an application must be able to tolerate some pauses. ソフト リアルタイムの基準では、95% の操作が時間どおりに完了する必要があります。A criterion for soft real time is that 95% of the operations must finish on time.

同時実行ガベージ コレクションでは、コレクションの実行中もマネージド スレッドを実行できるため、一時停止は最小限に抑えられます。In concurrent garbage collection, managed threads are allowed to run during a collection, which means that pauses are very minimal.

短期ガベージ コレクション (ジェネレーション 0 および 1) は数ミリ秒しかかからないため、一般に一時停止を減らすことは不可能です。Ephemeral garbage collections (generations 0 and 1) last only a few milliseconds, so decreasing pauses is usually not feasible. 一方、ジェネレーション 2 のコレクションでは、アプリケーションによる割り当て要求のパターンを変更することによって一時停止を減らすことができます。However, you can decrease the pauses in generation 2 collections by changing the pattern of allocation requests by an application.

より正確な方法として、ガベージ コレクション ETW イベントを使用することもできます。Another, more accurate, method is to use garbage collection ETW events. 一連のイベントにタイム スタンプを追加して区別することにより、コレクションのタイミングを特定できます。You can find the timings for collections by adding the time stamp differences for a sequence of events. コレクションのシーケンス全体には、実行エンジンの中断、ガベージ コレクション自体、および実行エンジンの再開が含まれます。The whole collection sequence includes suspension of the execution engine, the garbage collection itself, and the resumption of the execution engine.

ガベージ コレクションの通知を使用すると、サーバーでジェネレーション 2 のコレクションが発生しそうかどうか、要求を別のサーバーに再ルーティングすることで一時停止の問題を緩和できるかどうかを確認できます。You can use Garbage Collection Notifications to determine whether a server is about to have a generation 2 collection, and whether rerouting requests to another server could ease any problems with pauses.

パフォーマンス チェックPerformance checks
ガベージ コレクションの継続時間を確認する。Determine the length of time in a garbage collection.

ガベージ コレクションが発生した原因を確認する。Determine what caused a garbage collection.

問題: ジェネレーション 0 が大きすぎるIssue: Generation 0 Is Too Big

64 ビット システムでは、ジェネレーション 0 のオブジェクトの数が増える傾向があります。ワークステーションのガベージ コレクションではなくサーバーのガベージ コレクションを使用している場合は特にその傾向が強くなります。Generation 0 is likely to have a larger number of objects on a 64-bit system, especially when you use server garbage collection instead of workstation garbage collection. それらの環境では、ジェネレーション 0 のガベージ コレクションをトリガーするしきい値が高いので、ジェネレーション 0 のコレクションが非常に大きくなる可能性があるためです。This is because the threshold to trigger a generation 0 garbage collection is higher in these environments, and generation 0 collections can get much bigger. アプリケーションで、ガベージ コレクションがトリガーされる前により多くのメモリを割り当てると、パフォーマンスが向上します。Performance is improved when an application allocates more memory before a garbage collection is triggered.

問題: ガベージ コレクションの実行時の CPU 使用率が高すぎるIssue: CPU Usage During a Garbage Collection Is Too High

ガベージ コレクションの実行時には CPU 使用率が高くなります。CPU usage will be high during a garbage collection. ガベージ コレクションに大量の処理時間が費やされている場合は、コレクションの発生頻度が高すぎるか、コレクションの継続時間が長すぎます。If a significant amount of process time is spent in a garbage collection, the number of collections is too frequent or the collection is lasting too long. マネージド ヒープに対するオブジェクトの割り当ての速度を上げるとガベージ コレクションの発生頻度が高くなります。An increased allocation rate of objects on the managed heap causes garbage collection to occur more frequently. 割り当ての速度を下げるとガベージ コレクションの発生頻度が低くなります。Decreasing the allocation rate reduces the frequency of garbage collections.

割り当ての速度を監視するには、Allocated Bytes/second パフォーマンス カウンターを使用します。You can monitor allocation rates by using the Allocated Bytes/second performance counter. 詳細については、「.NET Framework のパフォーマンス カウンター」を参照してください。For more information, see Performance Counters in the .NET Framework.

コレクションの継続時間は、主に、割り当て後に残ったオブジェクトの数によって決まります。The duration of a collection is primarily a factor of the number of objects that survive after allocation. コレクションの対象となるオブジェクトが数多く残っていると、ガベージ コレクターが大量のメモリを処理しなければならなくなります。The garbage collector must go through a large amount of memory if many objects remain to be collected. 残存オブジェクトの圧縮には時間がかかります。The work to compact the survivors is time-consuming. コレクションの実行中に処理されたオブジェクトの数を確認するには、デバッガーで特定のジェネレーションのガベージ コレクションの終了時にブレークポイントを設定します。To determine how many objects were handled during a collection, set a breakpoint in the debugger at the end of a garbage collection for a specified generation.

パフォーマンス チェックPerformance checks
CPU の使用率が高いのはガベージ コレクションのためかどうかを確認する。Determine if high CPU usage is caused by garbage collection.

ガベージ コレクションの終了時にブレークポイントを設定する。Set a breakpoint at the end of garbage collection.

ページのトップへBack to top

トラブルシューティングのガイドラインTroubleshooting Guidelines

ここでは、調査を開始するときに考慮する必要があるガイドラインについて説明します。This section describes guidelines that you should consider as you begin your investigations.

ワークステーションのガベージ コレクションかサーバーのガベージ コレクションかWorkstation or Server Garbage Collection

使用しているガベージ コレクションの種類が正しいかどうかを確認します。Determine if you are using the correct type of garbage collection. アプリケーションで複数のスレッドおよびオブジェクト インスタンスを使用する場合は、ワークステーションのガベージ コレクションではなくサーバーのガベージ コレクションを使用します。If your application uses multiple threads and object instances, use server garbage collection instead of workstation garbage collection. サーバーのガベージ コレクションは複数のスレッドで動作しますが、ワークステーションのガベージ コレクションでは、アプリケーションの複数のインスタンスでそれぞれ専用のガベージ コレクション スレッドを実行する必要があるため、CPU 時間の競合が発生します。Server garbage collection operates on multiple threads, whereas workstation garbage collection requires multiple instances of an application to run their own garbage collection threads and compete for CPU time.

負荷が低く、バックグラウンドでタスクを実行することの少ないアプリケーション (サービスなど) では、同時実行ガベージ コレクションを無効にしてワークステーションのガベージ コレクションを使用できます。An application that has a low load and that performs tasks infrequently in the background, such as a service, could use workstation garbage collection with concurrent garbage collection disabled.

いつマネージド ヒープのサイズを測定するかWhen to Measure the Managed Heap Size

プロファイラーを使用しない場合、パフォーマンスの問題を効果的に診断するには、一貫した測定パターンを確立する必要があります。Unless you are using a profiler, you will have to establish a consistent measuring pattern to effectively diagnose performance issues. スケジュールを確立する際の考慮事項を以下に示します。Consider the following points to establish a schedule:

  • ジェネレーション 2 のガベージ コレクションの後に測定する場合は、マネージド ヒープ全体からガベージ (死んだ状態のオブジェクト) がなくなっています。If you measure after a generation 2 garbage collection, the entire managed heap will be free of garbage (dead objects).

  • ジェネレーション 0 のガベージ コレクションの直後に測定する場合は、ジェネレーション 1 と 2 のオブジェクトのコレクションはまだ行われていません。If you measure immediately after a generation 0 garbage collection, the objects in generations 1 and 2 will not be collected yet.

  • ガベージ コレクションの直前に測定する場合は、どのくらいの割り当てが行われるとガベージ コレクションが開始されるのかが測定されます。If you measure immediately before a garbage collection, you will measure as much allocation as possible before the garbage collection starts.

  • ガベージ コレクションの実行中に測定するのには問題があります。ガベージ コレクターのデータ構造が走査可能な状態になっていないので、完全な結果が得られない可能性があるためです。Measuring during a garbage collection is problematic, because the garbage collector data structures are not in a valid state for traversal and may not be able to give you the complete results. これは仕様に基づく制限事項です。This is by design.

  • 同時実行ガベージ コレクションを有効にしてワークステーションのガベージ コレクションを使用している場合は、解放されたオブジェクトが圧縮されないため、ヒープ サイズが変わらなかったり大きくなっていたりすることがあります (断片化のために大きく見えることがあります)。When you are using workstation garbage collection with concurrent garbage collection, the reclaimed objects are not compacted, so the heap size can be the same or larger (fragmentation can make it appear to be larger).

  • ジェネレーション 2 の同時実行ガベージ コレクションは、物理メモリの負荷が高すぎると延期されます。Concurrent garbage collection on generation 2 is delayed when the physical memory load is too high.

マネージド ヒープを測定するためのブレークポイントを設定する方法を以下に示します。The following procedure describes how to set a breakpoint so that you can measure the managed heap.

ガベージ コレクションの終了時にブレークポイントを設定するにはTo set a breakpoint at the end of garbage collection
  • SOS デバッガー拡張が読み込まれた WinDbg で、次のコマンドを入力します。In WinDbg with the SOS debugger extension loaded, type the following command:

    bp mscorwks!WKS::GCHeap::RestartEE "j (dwo(mscorwks!WKS::GCHeap::GcCondemnedGeneration)==2) 'kb';'g'"bp mscorwks!WKS::GCHeap::RestartEE "j (dwo(mscorwks!WKS::GCHeap::GcCondemnedGeneration)==2) 'kb';'g'"

    GcCondemnedGeneration は、目的のジェネレーションに設定します。where GcCondemnedGeneration is set to the desired generation. このコマンドにはプライベート シンボルが必要です。This command requires private symbols.

    これにより、ジェネレーション 2 のオブジェクトがガベージ コレクションのために解放された後に RestartEE が実行されると、実行が中断されます。This command forces a break if RestartEE is executed after generation 2 objects have been reclaimed for garbage collection.

    サーバーのガベージ コレクションでは、RestartEE を呼び出すスレッドは 1 つだけなので、ジェネレーション 2 のガベージ コレクションの実行中に 1 回だけブレークポイントが発生します。In server garbage collection, only one thread calls RestartEE, so the breakpoint will occur only once during a generation 2 garbage collection.

ページのトップへBack to top

パフォーマンス チェックの手順Performance Check Procedures

ここでは、パフォーマンスの問題の原因を切り分けるための以下の手順について説明します。This section describes the following procedures to isolate the cause of your performance issue:

問題の原因がガベージ コレクションにあるかどうかを確認するにはTo determine whether the problem is caused by garbage collection
  • 次の 2 つのメモリ パフォーマンス カウンターを調べます。Examine the following two memory performance counters:

    • % Time in GC% Time in GC. 前回のガベージ コレクション サイクルの後にガベージ コレクションの実行に費やされた経過時間の割合を表示します。Displays the percentage of elapsed time that was spent performing a garbage collection after the last garbage collection cycle. このカウンターを使用すると、ガベージ コレクターがマネージド ヒープの領域を確保するために費やしている時間が長すぎないかどうかを確認できます。Use this counter to determine whether the garbage collector is spending too much time to make managed heap space available. ガベージ コレクションに費やされている時間が比較的短い場合は、マネージド ヒープ以外のリソースに問題があると考えられます。If the time spent in garbage collection is relatively low, that could indicate a resource problem outside the managed heap. このカウンターは、同時実行ガベージ コレクションやバックグラウンド ガベージ コレクションでは正確な値が得られない可能性があります。This counter may not be accurate when concurrent or background garbage collection is involved.

    • # Total committed Bytes# Total committed Bytes. ガベージ コレクターによって現在コミットされている仮想メモリの量を表示します。Displays the amount of virtual memory currently committed by the garbage collector. このカウンターを使用すると、アプリケーションが使用しているメモリのうちガベージ コレクターによって消費されているメモリが多すぎないかどうかを確認できます。Use this counter to determine whether the memory consumed by the garbage collector is an excessive portion of the memory that your application uses.

    ほとんどのメモリ パフォーマンス カウンターは、各ガベージ コレクションの終了時に更新されます。Most of the memory performance counters are updated at the end of each garbage collection. そのため、情報を得ようとしている時点の状態が反映されていない場合もあります。Therefore, they may not reflect the current conditions that you want information about.

メモリ不足の例外がマネージド例外かどうかを確認するにはTo determine whether the out-of-memory exception is managed
  1. SOS デバッガー拡張が読み込まれた WinDbg または Visual Studio デバッガーで、pe (print exception) コマンドを入力します。In the WinDbg or Visual Studio debugger with the SOS debugger extension loaded, type the print exception (pe) command:

    !pe!pe

    マネージド例外の場合は、次の例のように、OutOfMemoryException が例外の種類として表示されます。If the exception is managed, OutOfMemoryException is displayed as the exception type, as shown in the following example.

    Exception object: 39594518
    Exception type: System.OutOfMemoryException
    Message: <none>
    InnerException: <none>
    StackTrace (generated):
    
  2. 出力に例外が明記されていない場合は、メモリ不足の例外が発生したスレッドを特定する必要があります。If the output does not specify an exception, you have to determine which thread the out-of-memory exception is from. デバッガーで次のコマンドを入力して、すべてのスレッドとその呼び出し履歴を表示します。Type the following command in the debugger to show all the threads with their call stacks:

    ~*kb~*kb

    履歴に例外の呼び出しが含まれているスレッドは、RaiseTheException 引数によって示されます。The thread with the stack that has exception calls is indicated by the RaiseTheException argument. これはマネージド例外オブジェクトです。This is the managed exception object.

    28adfb44 7923918f 5b61f2b4 00000000 5b61f2b4 mscorwks!RaiseTheException+0xa0
    
  3. 次のコマンドを使用して、入れ子になった例外をダンプします。You can use the following command to dump nested exceptions.

    !pe -nested!pe -nested

    例外が見つからない場合、そのメモリ不足の例外は、アンマネージ コードで発生した例外です。If you do not find any exceptions, the out-of-memory exception originated from unmanaged code.

予約できる仮想メモリの量を確認するにはTo determine how much virtual memory can be reserved
  • SOS デバッガー拡張が読み込まれた WinDbg で次のコマンドを入力して、最も大きな空き領域を取得します。In WinDbg with the SOS debugger extension loaded, type the following command to get the largest free region:

    !address -summary!address -summary

    次の例のように、最も大きな空き領域が表示されます。The largest free region is displayed as shown in the following output.

    Largest free region: Base 54000000 - Size 0003A980
    

    この例では、最も大きな空き領域のサイズは約 24000 KB (16 進形式では 3A980) です。In this example, the size of the largest free region is approximately 24000 KB (3A980 in hexadecimal). これは、ガベージ コレクターのセグメントに必要なサイズよりはるかに小さいサイズです。This region is much smaller than what the garbage collector needs for a segment.

    または-or-

  • vmstat コマンドを使用します。Use the vmstat command:

    !vmstat!vmstat

    MAXIMUM 列の最大値が最も大きな空き領域です。以下に例を示します。The largest free region is the largest value in the MAXIMUM column, as shown in the following output.

    TYPE        MINIMUM   MAXIMUM     AVERAGE   BLK COUNT   TOTAL
    ~~~~        ~~~~~~~   ~~~~~~~     ~~~~~~~   ~~~~~~~~~~  ~~~~
    Free:
    Small       8K        64K         46K       36          1,671K
    Medium      80K       864K        349K      3           1,047K
    Large       1,384K    1,278,848K  151,834K  12          1,822,015K
    Summary     8K        1,278,848K  35,779K   51          1,824,735K
    

十分な物理メモリがあるかどうかを確認するにはTo determine whether there is enough physical memory
  1. Windows タスク マネージャーを起動します。Start Windows Task Manager.

  2. [パフォーマンス] タブで、コミットの値を確認しますOn the Performance tab, look at the committed value. (Windows 7 では [システム][コミット (KB)] )。(In Windows 7, look at Commit (KB) in the System group.)

    [合計][制限値] に近い場合は、物理メモリが不足しています。If the Total is close to the Limit, you are running low on physical memory.

マネージド ヒープでコミットしているメモリの量を確認するにはTo determine how much memory the managed heap is committing
  • マネージド ヒープでコミットしているバイト数を確認するには、# Total committed bytes メモリ パフォーマンス カウンターを使用します。Use the # Total committed bytes memory performance counter to get the number of bytes that the managed heap is committing. ガベージ コレクターは、セグメントのチャンクを必要に応じてコミットします。すべてを同時にコミットするのではありません。The garbage collector commits chunks on a segment as needed, not all at the same time.

    注意

    # Bytes in all Heaps パフォーマンス カウンターは使用しないでください。このパフォーマンス カウンターによって表されるのは、マネージド ヒープの実際のメモリ使用量ではありません。Do not use the # Bytes in all Heaps performance counter, because it does not represent actual memory usage by the managed heap. この値にはジェネレーションのサイズが含まれますが、それは、実質的にはジェネレーションのしきい値 (ジェネレーションがオブジェクトでいっぱいになった場合にガベージ コレクションが発生するサイズ) です。The size of a generation is included in this value and is actually its threshold size, that is, the size that induces a garbage collection if the generation is filled with objects. したがって、この値は、通常は 0 になります。Therefore, this value is usually zero.

マネージド ヒープで予約されているメモリの量を確認するにはTo determine how much memory the managed heap reserves
  • # Total reserved bytes メモリ パフォーマンス カウンターを使用します。Use the # Total reserved bytes memory performance counter.

    ガベージ コレクターはメモリをセグメント単位で予約します。セグメントの開始位置を特定するには eeheap コマンドを使用します。The garbage collector reserves memory in segments, and you can determine where a segment starts by using the eeheap command.

    重要

    ガベージ コレクターが各セグメントに割り当てるメモリ量を判別することは可能ですが、セグメント サイズは実装に固有であり、定期的な更新プログラムによる場合を含め、いつでも変更されることがあります。Although you can determine the amount of memory the garbage collector allocates for each segment, segment size is implementation-specific and is subject to change at any time, including in periodic updates. アプリでは、セグメント サイズを推測することや、特定のセグメント サイズに依存することを絶対に避けてください。また、セグメントの割り当てに使用可能なメモリの量を構成しようとしてもなりません。Your app should never make assumptions about or depend on a particular segment size, nor should it attempt to configure the amount of memory available for segment allocations.

  • SOS デバッガー拡張が読み込まれた WinDbg または Visual Studio デバッガーで、次のコマンドを入力します。In the WinDbg or Visual Studio debugger with the SOS debugger extension loaded, type the following command:

    !eeheap -gc!eeheap -gc

    この結果は次のようになります。The result is as follows.

    Number of GC Heaps: 2
    ------------------------------
    Heap 0 (002db550)
    generation 0 starts at 0x02abe29c
    generation 1 starts at 0x02abdd08
    generation 2 starts at 0x02ab0038
    ephemeral segment allocation context: none
      segment    begin allocated     size
    02ab0000 02ab0038  02aceff4 0x0001efbc(126908)
    Large object heap starts at 0x0aab0038
      segment    begin allocated     size
    0aab0000 0aab0038  0aab2278 0x00002240(8768)
    Heap Size   0x211fc(135676)
    ------------------------------
    Heap 1 (002dc958)
    generation 0 starts at 0x06ab1bd8
    generation 1 starts at 0x06ab1bcc
    generation 2 starts at 0x06ab0038
    ephemeral segment allocation context: none
      segment    begin allocated     size
    06ab0000 06ab0038  06ab3be4 0x00003bac(15276)
    Large object heap starts at 0x0cab0038
      segment    begin allocated     size
    0cab0000 0cab0038  0cab0048 0x00000010(16)
    Heap Size    0x3bbc(15292)
    ------------------------------
    GC Heap Size   0x24db8(150968)
    

    "segment" によって示されるアドレスがセグメントの開始アドレスです。The addresses indicated by "segment" are the starting addresses of the segments.

ジェネレーション 2 の大きいオブジェクトを確認するにはTo determine large objects in generation 2
  • SOS デバッガー拡張が読み込まれた WinDbg または Visual Studio デバッガーで、次のコマンドを入力します。In the WinDbg or Visual Studio debugger with the SOS debugger extension loaded, type the following command:

    !dumpheap –stat!dumpheap –stat

    dumpheap は、マネージド ヒープが大きいと完了までにしばらくかかります。If the managed heap is big, dumpheap may take a while to finish.

    最も多くの領域を使用しているオブジェクトは出力の最後の数行に表示されるため、そこを分析します。You can start analyzing from the last few lines of the output, because they list the objects that use the most space. 次に例を示します。For example:

    2c6108d4   173712     14591808 DevExpress.XtraGrid.Views.Grid.ViewInfo.GridCellInfo
    00155f80      533     15216804      Free
    7a747c78   791070     15821400 System.Collections.Specialized.ListDictionary+DictionaryNode
    7a747bac   700930     19626040 System.Collections.Specialized.ListDictionary
    2c64e36c    78644     20762016 DevExpress.XtraEditors.ViewInfo.TextEditViewInfo
    79124228   121143     29064120 System.Object[]
    035f0ee4    81626     35588936 Toolkit.TlkOrder
    00fcae40     6193     44911636 WaveBasedStrategy.Tick_Snap[]
    791242ec    40182     90664128 System.Collections.Hashtable+bucket[]
    790fa3e0  3154024    137881448 System.String
    Total 8454945 objects
    

    最後の行のオブジェクトは文字列で、最も多くの領域を占有しています。The last object listed is a string and occupies the most space. したがって、アプリケーションで文字列オブジェクトを最適化する方法を調べます。You can examine your application to see how your string objects can be optimized. サイズが 150 ~ 200 バイトの文字列を表示するには、次のコマンドを入力します。To see strings that are between 150 and 200 bytes, type the following:

    !dumpheap -type System.String -min 150 -max 200!dumpheap -type System.String -min 150 -max 200

    結果の例を次に示します。An example of the results is as follows.

    Address  MT           Size  Gen
    1875d2c0 790fa3e0      152    2 System.String HighlightNullStyle_Blotter_PendingOrder-11_Blotter_PendingOrder-11
    …
    

    ID に文字列の代わりに整数を使用すると、効率を改善できます。Using an integer instead of a string for an ID can be more efficient. 同じ文字列が何千回も繰り返し使用されている場合は、文字列インターンの使用を検討します。If the same string is being repeated thousands of times, consider string interning. 文字列インターンの詳細については、String.Intern メソッドのリファレンス トピックを参照してください。For more information about string interning, see the reference topic for the String.Intern method.

オブジェクトへの参照を確認するにはTo determine references to objects
  • SOS デバッガー拡張が読み込まれた WinDbg で次のコマンドを入力して、オブジェクトへの参照を表示します。In WinDbg with the SOS debugger extension loaded, type the following command to list references to objects:

    !gcroot!gcroot

    -or-

  • 特定のオブジェクトの参照を確認するには、アドレスを含めます。To determine the references for a specific object, include the address:

    !gcroot 1c37b2ac!gcroot 1c37b2ac

    履歴で見つかるルートは誤検出である可能性があります。Roots found on stacks may be false positives. 詳細については、コマンド !help gcroot を使用してください。For more information, use the command !help gcroot.

    ebx:Root:19011c5c(System.Windows.Forms.Application+ThreadContext)->
    19010b78(DemoApp.FormDemoApp)->
    19011158(System.Windows.Forms.PropertyStore)->
    … [omitted]
    1c3745ec(System.Data.DataTable)->
    1c3747a8(System.Data.DataColumnCollection)->
    1c3747f8(System.Collections.Hashtable)->
    1c376590(System.Collections.Hashtable+bucket[])->
    1c376c98(System.Data.DataColumn)->
    1c37b270(System.Data.Common.DoubleStorage)->
    1c37b2ac(System.Double[])
    Scan Thread 0 OSTHread 99c
    Scan Thread 6 OSTHread 484
    

    gcroot コマンドは、完了までに時間がかかることがあります。The gcroot command can take a long time to finish. ガベージ コレクションによって解放されないオブジェクトはライブ オブジェクトです。Any object that is not reclaimed by garbage collection is a live object. したがって、そのオブジェクトを直接的または間接的に参照しているルートがあるため、gcroot でそのオブジェクトへのパス情報が返されます。This means that some root is directly or indirectly holding onto the object, so gcroot should return path information to the object. 返されたグラフを調べて、それらのオブジェクトがまだ参照されている理由を確認する必要があります。You should examine the graphs returned and see why these objects are still referenced.

ファイナライザーが実行されたかどうかを確認するにはTo determine whether a finalizer has been run
  • 次のコードを含むテスト プログラムを実行します。Run a test program that contains the following code:

    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    

    このテストで問題が解決される場合は、ファイナライザーが実行されていないためにガベージ コレクターによって解放されないオブジェクトがあったことになります。If the test resolves the problem, this means that the garbage collector was not reclaiming objects, because the finalizers for those objects had been suspended. GC.WaitForPendingFinalizers メソッドを使用すると、ファイナライザーがタスクを完了できるようになるため、問題が解決されます。The GC.WaitForPendingFinalizers method enables the finalizers to complete their tasks, and fixes the problem.

終了待機中のオブジェクトがないかどうかを確認するにはTo determine whether there are objects waiting to be finalized
  1. SOS デバッガー拡張が読み込まれた WinDbg または Visual Studio デバッガーで、次のコマンドを入力します。In the WinDbg or Visual Studio debugger with the SOS debugger extension loaded, type the following command:

    !finalizequeue!finalizequeue

    終了準備が完了しているオブジェクトの数を確認します。Look at the number of objects that are ready for finalization. その数が多い場合は、それらのファイナライザーが実行されない理由、または実行が遅れている理由を調べる必要があります。If the number is high, you must examine why these finalizers cannot progress at all or cannot progress fast enough.

  2. スレッドの出力を取得するには、次のコマンドを入力します。To get an output of threads, type the following command:

    threads -specialthreads -special

    次のような出力が表示されます。This command provides output such as the following.

       OSID     Special thread type
    2    cd0    DbgHelper
    3    c18    Finalizer
    4    df0    GC SuspendEE
    

    ファイナライザー スレッドは、現在実行されているファイナライザーを示します (存在する場合)。The finalizer thread indicates which finalizer, if any, is currently being run. 実行中のファイナライザー スレッドが存在しない場合は、処理の開始を通知するイベントを待機しています。When a finalizer thread is not running any finalizers, it is waiting for an event to tell it to do its work. ファイナライザー スレッドは、ほとんどの場合この状態にあります。THREAD_HIGHEST_PRIORITY で実行されるので、実行するファイナライザーがあればすぐに実行されるためです。Most of the time you will see the finalizer thread in this state because it runs at THREAD_HIGHEST_PRIORITY and is supposed to finish running finalizers, if any, very quickly.

マネージド ヒープの空き領域の容量を確認するにはTo determine the amount of free space in the managed heap
  • SOS デバッガー拡張が読み込まれた WinDbg または Visual Studio デバッガーで、次のコマンドを入力します。In the WinDbg or Visual Studio debugger with the SOS debugger extension loaded, type the following command:

    !dumpheap -type Free -stat!dumpheap -type Free -stat

    このコマンドは、次の例に示すように、マネージド ヒープのすべての空きオブジェクトの合計サイズを表示します。This command displays the total size of all the free objects on the managed heap, as shown in the following example.

    total 230 objects
    Statistics:
          MT    Count    TotalSize Class Name
    00152b18      230     40958584      Free
    Total 230 objects
    
  • ジェネレーション 0 の空き領域を確認するには、次のコマンドを入力して、ジェネレーション別のメモリ消費情報を表示します。To determine the free space in generation 0, type the following command for memory consumption information by generation:

    !eeheap -gc!eeheap -gc

    次のような出力が表示されます。This command displays output similar to the following. 最後の行には短期セグメントが表示されています。The last line shows the ephemeral segment.

    Heap 0 (0015ad08)
    generation 0 starts at 0x49521f8c
    generation 1 starts at 0x494d7f64
    generation 2 starts at 0x007f0038
    ephemeral segment allocation context: none
    segment  begin     allocated  size
    00178250 7a80d84c  7a82f1cc   0x00021980(137600)
    00161918 78c50e40  78c7056c   0x0001f72c(128812)
    007f0000 007f0038  047eed28   0x03ffecf0(67103984)
    3a120000 3a120038  3a3e84f8   0x002c84c0(2917568)
    46120000 46120038  49e05d04   0x03ce5ccc(63855820)
    
  • ジェネレーション 0 によって使用されている領域を計算します。Calculate the space used by generation 0:

    ?49e05d04-0x49521f8c? 49e05d04-0x49521f8c

    この結果は次のようになります。The result is as follows. ジェネレーション 0 は約 9 MB です。Generation 0 is approximately 9 MB.

    Evaluate expression: 9321848 = 008e3d78
    
  • 次のコマンドは、ジェネレーション 0 の範囲にある空き領域をダンプします。The following command dumps the free space within the generation 0 range:

    !dumpheap -type Free -stat 0x49521f8c 49e05d04!dumpheap -type Free -stat 0x49521f8c 49e05d04

    この結果は次のようになります。The result is as follows.

    ------------------------------
    Heap 0
    total 409 objects
    ------------------------------
    Heap 1
    total 0 objects
    ------------------------------
    Heap 2
    total 0 objects
    ------------------------------
    Heap 3
    total 0 objects
    ------------------------------
    total 409 objects
    Statistics:
          MT    Count TotalSize Class Name
    0015a498      409   7296540      Free
    Total 409 objects
    

    この出力は、ヒープのジェネレーション 0 の部分で 9 MB の領域がオブジェクトに使用されていて、7 MB が空いていることを示しています。This output shows that the generation 0 portion of the heap is using 9 MB of space for objects and has 7 MB free. この分析から、ジェネレーション 0 がどの程度断片化に関与しているのかがわかります。This analysis shows the extent to which generation 0 contributes to fragmentation. この分のヒープ使用量は、長期間のオブジェクトによる断片化の原因となる合計容量から除外する必要があります。This amount of heap usage should be discounted from the total amount as the cause of fragmentation by long-term objects.

固定されたオブジェクトの数を確認するにはTo determine the number of pinned objects
  • SOS デバッガー拡張が読み込まれた WinDbg または Visual Studio デバッガーで、次のコマンドを入力します。In the WinDbg or Visual Studio debugger with the SOS debugger extension loaded, type the following command:

    !gchandles!gchandles

    次の例に示すように、固定ハンドルの数を含む統計情報が表示されます。The statistics displayed includes the number of pinned handles, as the following example shows.

    GC Handle Statistics:
    Strong Handles:      29
    Pinned Handles:      10
    

ガベージ コレクションの継続時間を確認するにはTo determine the length of time in a garbage collection
  • % Time in GC メモリ パフォーマンス カウンターを調べます。Examine the % Time in GC memory performance counter.

    この値は、サンプル間隔の時間を使用して計算します。The value is calculated by using a sample interval time. このカウンターは各ガベージ コレクションの終了時に更新されるため、サンプル間隔の間にコレクションが発生しなかった場合は前のサンプルと同じ値になります。Because the counters are updated at the end of each garbage collection, the current sample will have the same value as the previous sample if no collections occurred during the interval.

    コレクションの時間は、サンプル間隔の時間にパーセント値を掛けて計算します。Collection time is obtained by multiplying the sample interval time with the percentage value.

    次のデータには 4 つのサンプリング間隔が示されています。サンプリング間隔の時間は 2 秒で、8 秒間にわたって調査が行われています。The following data shows four sampling intervals of two seconds, for an 8-second study. Gen0Gen1Gen2 の各列には、そのジェネレーションでその間隔の間に発生したガベージ コレクションの番号が表示されています。The Gen0, Gen1, and Gen2 columns show the number of garbage collections that occurred during that interval for that generation.

    Interval    Gen0    Gen1    Gen2    % Time in GC
            1       9       3       1              10
            2      10       3       1               1
            3      11       3       1               3
            4      11       3       1               3
    

    この情報からは、ガベージ コレクションが発生した時間はわかりませんが、特定の時間間隔の間に発生したガベージ コレクションの番号を特定できます。This information does not show when the garbage collection occurred, but you can determine the number of garbage collections that occurred in an interval of time. 最悪のケースでは、ジェネレーション 0 の 10 番目のガベージ コレクションが間隔 2 の開始時に終了し、ジェネレーション 0 の 11 番目のガベージ コレクションが間隔 5 の終了時に終了したことになります。Assuming the worst case, the tenth generation 0 garbage collection finished at the start of the second interval, and the eleventh generation 0 garbage collection finished at the end of the fifth interval. 10 番目のガベージ コレクションが終了してから 11 番目のガベージ コレクションが終了するまでの時間は約 2 秒で、パフォーマンス カウンターの値は 3% になっているため、ジェネレーション 0 の 11 番目のガベージ コレクションの継続時間は 60 ミリ秒 (2 秒 * 3%) になります。The time between the end of the tenth and the end of the eleventh garbage collection is about 2 seconds, and the performance counter shows 3%, so the duration of the eleventh generation 0 garbage collection was (2 seconds * 3% = 60ms).

    次の例には 5 つの間隔があります。In this example, there are 5 periods.

    Interval    Gen0    Gen1    Gen2     % Time in GC
            1       9       3       1                3
            2      10       3       1                1
            3      11       4       2                1
            4      11       4       2                1
            5      11       4       2               20
    

    ジェネレーション 2 の 2 番目のガベージ コレクションは、間隔 3 の間に開始され、間隔 5 で終了しています。The second generation 2 garbage collection started during the third interval and finished at the fifth interval. 最悪のケースでは、このガベージ コレクションの前のガベージ コレクションは、間隔 2 の開始時に終了したジェネレーション 0 のコレクションで、このジェネレーション 2 のガベージ コレクション自体は、間隔 5 の終了時に終了したことになります。Assuming the worst case, the last garbage collection was for a generation 0 collection that finished at the start of the second interval, and the generation 2 garbage collection finished at the end of the fifth interval. したがって、そのジェネレーション 0 のガベージ コレクションが終了してからこのジェネレーション 2 のガベージ コレクションが終了するまでの時間は 4 秒になります。Therefore, the time between the end of the generation 0 garbage collection and the end of the generation 2 garbage collection is 4 seconds. % Time in GC カウンターの値は 20% なので、このジェネレーション 2 のガベージ コレクションの継続時間は最大で 800 ミリ秒 (4 秒 * 20%) になります。Because the % Time in GC counter is 20%, the maximum amount of time the generation 2 garbage collection could have taken is (4 seconds * 20% = 800ms).

  • ガベージ コレクション ETW イベントを使用してガベージ コレクションの長さを確認し、その情報を分析してガベージ コレクションの継続時間を特定することもできます。Alternatively, you can determine the length of a garbage collection by using garbage collection ETW events, and analyze the information to determine the duration of garbage collection.

    たとえば、次のデータは、非同時実行ガベージ コレクションの実行中に発生したイベント シーケンスを示しています。For example, the following data shows an event sequence that occurred during a non-concurrent garbage collection.

    Timestamp    Event name
    513052        GCSuspendEEBegin_V1
    513078        GCSuspendEEEnd
    513090        GCStart_V1
    517890        GCEnd_V1
    517894        GCHeapStats
    517897        GCRestartEEBegin
    517918        GCRestartEEEnd
    

    マネージド スレッドの中断に 26 マイクロ秒かかっています (GCSuspendEEEndGCSuspendEEBegin_V1)。Suspending the managed thread took 26us (GCSuspendEEEndGCSuspendEEBegin_V1).

    実際のガベージ コレクションに 4.8 ミリ秒かかっています (GCEnd_V1GCStart_V1)。The actual garbage collection took 4.8ms (GCEnd_V1GCStart_V1).

    マネージド スレッドの再開に 21 マイクロ秒かかっています (GCRestartEEEndGCRestartEEBegin)。Resuming the managed threads took 21us (GCRestartEEEndGCRestartEEBegin).

    次の例は、バックグラウンド ガベージ コレクションの出力を示しています。この出力には、process、thread、および event field が含まれていますThe following output provides an example for background garbage collection, and includes the process, thread, and event fields. (すべてのデータが示されているわけではありません)。(Not all data is shown.)

    timestamp(us)    event name            process    thread    event field
    42504385        GCSuspendEEBegin_V1    Test.exe    4372             1
    42504648        GCSuspendEEEnd         Test.exe    4372
    42504816        GCStart_V1             Test.exe    4372        102019
    42504907        GCStart_V1             Test.exe    4372        102020
    42514170        GCEnd_V1               Test.exe    4372
    42514204        GCHeapStats            Test.exe    4372        102020
    42832052        GCRestartEEBegin       Test.exe    4372
    42832136        GCRestartEEEnd         Test.exe    4372
    63685394        GCSuspendEEBegin_V1    Test.exe    4744             6
    63686347        GCSuspendEEEnd         Test.exe    4744
    63784294        GCRestartEEBegin       Test.exe    4744
    63784407        GCRestartEEEnd         Test.exe    4744
    89931423        GCEnd_V1               Test.exe    4372        102019
    89931464        GCHeapStats            Test.exe    4372
    

    42504816 の GCStart_V1 イベントは、前のフィールドが 1 であるため、バックグラウンド ガベージ コレクションを示します。The GCStart_V1 event at 42504816 indicates that this is a background garbage collection, because the last field is 1. これは、次の番号のガベージ コレクションになります。This becomes garbage collection No. 102019.102019.

    バックグラウンド ガベージ コレクションを開始する前に短期ガベージ コレクションを実行する必要があるため、GCStart イベントが発生します。The GCStart event occurs because there is a need for an ephemeral garbage collection before you start a background garbage collection. これは、次の番号のガベージ コレクションになります。This becomes garbage collection No. 102020.102020.

    42514170 の時点で、ガベージ コレクションの番号はAt 42514170, garbage collection No. 102020 になり、終了します。102020 finishes. この時点でマネージド スレッドが再開されます。The managed threads are restarted at this point. スレッド 4372 で以上の処理が完了すると、バックグラウンド ガベージ コレクションがトリガーされます。This is completed on thread 4372, which triggered this background garbage collection.

    スレッド 4744 で中断が発生します。On thread 4744, a suspension occurs. このバックグラウンド ガベージ コレクションによってマネージド スレッドが中断されるのはこのときだけです。This is the only time at which the background garbage collection has to suspend managed threads. この中断の期間は約 99 ミリ秒です ((63784407-63685394)/1000)。This duration is approximately 99ms ((63784407-63685394)/1000).

    バックグラウンド ガベージ コレクションの GCEnd イベントは 89931423 で発生しています。The GCEnd event for the background garbage collection is at 89931423. したがって、このバックグラウンド ガベージ コレクションの継続時間は約 47 秒になります ((89931423-42504816)/1000)。This means that the background garbage collection lasted for about 47seconds ((89931423-42504816)/1000).

    マネージド スレッドの実行中には短期ガベージ コレクションが何度も発生する可能性があります。While the managed threads are running, you can see any number of ephemeral garbage collections occurring.

ガベージ コレクションが発生した原因を確認するにはTo determine what triggered a garbage collection
  • SOS デバッガー拡張が読み込まれた WinDbg または Visual Studio デバッガーで次のコマンドを入力して、すべてのスレッドとその呼び出し履歴を表示します。In the WinDbg or Visual Studio debugger with the SOS debugger extension loaded, type the following command to show all the threads with their call stacks:

    ~*kb~*kb

    次のような出力が表示されます。This command displays output similar to the following.

    0012f3b0 79ff0bf8 mscorwks!WKS::GCHeap::GarbageCollect
    0012f454 30002894 mscorwks!GCInterface::CollectGeneration+0xa4
    0012f490 79fa22bd fragment_ni!request.Main(System.String[])+0x48
    

    オペレーティング システムからのメモリ不足の通知によってガベージ コレクションが発生した場合も同じような呼び出し履歴になりますが、その場合はスレッドがファイナライザー スレッドになります。If the garbage collection was caused by a low memory notification from the operating system, the call stack is similar, except that the thread is the finalizer thread. ファイナライザー スレッドは、非同期のメモリ不足の通知を受け取って、ガベージ コレクションを発生させます。The finalizer thread gets an asynchronous low memory notification and induces the garbage collection.

    メモリの割り当てによってガベージ コレクションが発生した場合は、次のような履歴になります。If the garbage collection was caused by memory allocation, the stack appears as follows:

    0012f230 7a07c551 mscorwks!WKS::GCHeap::GarbageCollectGeneration
    0012f2b8 7a07cba8 mscorwks!WKS::gc_heap::try_allocate_more_space+0x1a1
    0012f2d4 7a07cefb mscorwks!WKS::gc_heap::allocate_more_space+0x18
    0012f2f4 7a02a51b mscorwks!WKS::GCHeap::Alloc+0x4b
    0012f310 7a02ae4c mscorwks!Alloc+0x60
    0012f364 7a030e46 mscorwks!FastAllocatePrimitiveArray+0xbd
    0012f424 300027f4 mscorwks!JIT_NewArr1+0x148
    000af70f 3000299f fragment_ni!request..ctor(Int32, Single)+0x20c
    0000002a 79fa22bd fragment_ni!request.Main(System.String[])+0x153
    

    最終的に Just-In-Time ヘルパー (JIT_New*) が GCHeap::GarbageCollectGeneration を呼び出します。A just-in-time helper (JIT_New*) eventually calls GCHeap::GarbageCollectGeneration. ジェネレーション 2 のガベージ コレクションが割り当てによって発生していると判断された場合は、ジェネレーション 2 のガベージ コレクションの対象になっているオブジェクトを確認し、それを回避する方法を特定する必要があります。If you determine that generation 2 garbage collections are caused by allocations, you must determine which objects are collected by a generation 2 garbage collection and how to avoid them. そのためには、ジェネレーション 2 のガベージ コレクションの開始時と終了時の違いを確認し、ジェネレーション 2 のコレクションを発生させたオブジェクトを特定します。That is, you want to determine the difference between the start and the end of a generation 2 garbage collection, and the objects that caused the generation 2 collection.

    たとえば、ジェネレーション 2 のコレクションの開始時の情報を表示するには、デバッガーで次のコマンドを入力します。For example, type the following command in the debugger to show the beginning of a generation 2 collection:

    !dumpheap –stat!dumpheap –stat

    出力の例を以下に示します (最も多くの領域を使用しているオブジェクトのみが示されています)。Example output (abridged to show the objects that use the most space):

    79124228    31857      9862328 System.Object[]
    035f0384    25668     11601936 Toolkit.TlkPosition
    00155f80    21248     12256296      Free
    79103b6c   297003     13068132 System.Threading.ReaderWriterLock
    7a747ad4   708732     14174640 System.Collections.Specialized.HybridDictionary
    7a747c78   786498     15729960 System.Collections.Specialized.ListDictionary+DictionaryNode
    7a747bac   700298     19608344 System.Collections.Specialized.ListDictionary
    035f0ee4    89192     38887712 Toolkit.TlkOrder
    00fcae40     6193     44911636 WaveBasedStrategy.Tick_Snap[]
    7912c444    91616     71887080 System.Double[]
    791242ec    32451     82462728 System.Collections.Hashtable+bucket[]
    790fa3e0  2459154    112128436 System.String
    Total 6471774 objects
    

    ジェネレーション 2 の終了時にも同じコマンドを実行します。Repeat the command at the end of generation 2:

    !dumpheap –stat!dumpheap –stat

    出力の例を以下に示します (最も多くの領域を使用しているオブジェクトのみが示されています)。Example output (abridged to show the objects that use the most space):

    79124228    26648      9314256 System.Object[]
    035f0384    25668     11601936 Toolkit.TlkPosition
    79103b6c   296770     13057880 System.Threading.ReaderWriterLock
    7a747ad4   708730     14174600 System.Collections.Specialized.HybridDictionary
    7a747c78   786497     15729940 System.Collections.Specialized.ListDictionary+DictionaryNode
    7a747bac   700298     19608344 System.Collections.Specialized.ListDictionary
    00155f80    13806     34007212      Free
    035f0ee4    89187     38885532 Toolkit.TlkOrder
    00fcae40     6193     44911636 WaveBasedStrategy.Tick_Snap[]
    791242ec    32370     82359768 System.Collections.Hashtable+bucket[]
    790fa3e0  2440020    111341808 System.String
    Total 6417525 objects
    

    出力の末尾から double[] オブジェクトがなくなっているため、これらがコレクションの対象になったことがわかります。The double[] objects disappeared from the end of the output, which means that they were collected. これらのオブジェクトは約 70 MB を占めています。These objects account for approximately 70 MB. その他のオブジェクトはあまり変更されていません。The remaining objects did not change much. したがって、これらの double[] オブジェクトが、このジェネレーション 2 のガベージ コレクションが発生した原因です。Therefore, these double[] objects were the reason why this generation 2 garbage collection occurred. ガベージ コレクションが発生した原因がわかったら、今度は、これらの double[] オブジェクトが存在する理由と、死んだ状態になった理由を特定します。Your next step is to determine why the double[] objects are there and why they died. コードの開発者にたずねることも、gcroot コマンドを使用して確認することもできます。You can ask the code developer where these objects came from, or you can use the gcroot command.

CPU の使用率が高いのはガベージ コレクションのためかどうかを確認するにはTo determine whether high CPU usage is caused by garbage collection
  • % Time in GC メモリ パフォーマンス カウンターの値と処理時間を互いに関連付けます。Correlate the % Time in GC memory performance counter value with the process time.

    % Time in GC の値と処理時間が同時に急激に増加している場合は、CPU の使用率が高いのはガベージ コレクションのためです。If the % Time in GC value spikes at the same time as process time, garbage collection is causing a high CPU usage. それ以外の場合は、アプリケーションのプロファイリングを実行して、使用率の高い箇所を見つけます。Otherwise, profile the application to find where the high usage is occurring.

関連項目See also