ガベージ コレクションの基礎Fundamentals of garbage collection

共通言語ランタイム (CLR) では、自動メモリ マネージャーとしてガベージ コレクター (GC) を使用できます。In the common language runtime (CLR), the garbage collector (GC) serves as an automatic memory manager. ガベージ コレクターは、アプリケーションのメモリの割り当てと解放を管理します。The garbage collector manages the allocation and release of memory for an application. マネージド コードを扱う開発者にとって、これは、メモリ管理タスクを実行するためのコードを記述する必要がないことを意味します。For developers working with managed code, this means that you don't have to write code to perform memory management tasks. 自動メモリ管理により、オブジェクトを解放し忘れたためにメモリ リークが発生する、既に解放されているオブジェクトのメモリにアクセスしようとするなどの一般的な問題を回避できます。Automatic memory management can eliminate common problems, such as forgetting to free an object and causing a memory leak or attempting to access memory for an object that's already been freed.

この記事では、ガベージ コレクションの主要な概念について説明します。This article describes the core concepts of garbage collection.

利点Benefits

ガベージ コレクターには、次のような利点があります。The garbage collector provides the following benefits:

  • 開発者がメモリを手動で解放する必要がなくなります。Frees developers from having to manually release memory.

  • オブジェクトが効率的にマネージド ヒープに割り当てられます。Allocates objects on the managed heap efficiently.

  • 使用されなくなったオブジェクトが解放され、メモリがクリアされてその後の割り当てに使用できるようになります。Reclaims objects that are no longer being used, clears their memory, and keeps the memory available for future allocations. マネージド オブジェクトは自動的にクリーンな内容で開始されるため、コンストラクターでデータ フィールドごとに初期化する必要はありません。Managed objects automatically get clean content to start with, so their constructors don't have to initialize every data field.

  • オブジェクトで別のオブジェクトの内容を使用できなくすることで、メモリの安全が確保されます。Provides memory safety by making sure that an object cannot use the content of another object.

メモリの基礎Fundamentals of memory

CLR のメモリに関する重要な概念の概要を以下に示します。The following list summarizes important CLR memory concepts.

  • 各プロセスは、分離された独自の仮想アドレス空間を持ちます。Each process has its own, separate virtual address space. 同じコンピューターのすべてのプロセスが同じ物理メモリとページ ファイル (存在する場合) を共有します。All processes on the same computer share the same physical memory and the page file, if there is one.

  • 32 ビット コンピューターでは、各プロセスが既定で 2 GB のユーザー モード仮想アドレス空間を持ちます。By default, on 32-bit computers, each process has a 2-GB user-mode virtual address space.

  • アプリケーション開発者が操作するのは仮想アドレス空間だけで、直接物理メモリを操作することはありません。As an application developer, you work only with virtual address space and never manipulate physical memory directly. マネージド ヒープの仮想メモリの割り当てと解放はガベージ コレクターによって行われます。The garbage collector allocates and frees virtual memory for you on the managed heap.

    ネイティブ コードを記述する場合は、Windows 関数を使用して仮想アドレス空間を操作します。If you're writing native code, you use Windows functions to work with the virtual address space. ネイティブ ヒープの仮想メモリの割り当てと解放はこれらの関数によって行われます。These functions allocate and free virtual memory for you on native heaps.

  • 仮想メモリには次の 3 つの状態があります。Virtual memory can be in three states:

    状態State 説明Description
    FreeFree 参照されていない、割り当てに使用できるメモリ ブロックです。The block of memory has no references to it and is available for allocation.
    予約されています。Reserved 使用できるように確保された、他の割り当て要求には使用できないメモリ ブロックです。The block of memory is available for your use and cannot be used for any other allocation request. ただし、このメモリ ブロックがコミットされるまではデータを格納できません。However, you cannot store data to this memory block until it is committed.
    CommittedCommitted 物理ストレージに割り当てられたメモリ ブロックです。The block of memory is assigned to physical storage.
  • 仮想アドレス空間は、断片化することがあります。Virtual address space can get fragmented. 断片化とは、アドレス空間に複数の空きブロック (ホールとも呼ばれます) がある状態です。This means that there are free blocks, also known as holes, in the address space. 仮想メモリの割り当てが要求された場合、仮想メモリ マネージャーは、その割り当て要求を満たすのに十分な大きさの単一の空きブロックを見つけなければなりません。When a virtual memory allocation is requested, the virtual memory manager has to find a single free block that is large enough to satisfy that allocation request. 2 GB の空き領域があっても、そのすべての空き領域が 1 つのアドレス ブロックの中にない場合、2 GB の領域を必要とする割り当ては失敗します。Even if you have 2 GB of free space, an allocation that requires 2 GB will be unsuccessful unless all of that free space is in a single address block.

  • メモリが足りなくなるのは、予約する仮想アドレス空間が足りなくなった場合か、コミットする物理領域が足りなくなった場合です。You can run out of memory if there isn't enough virtual address space to reserve or physical space to commit.

    ページ ファイルは、物理メモリの圧迫度 (物理メモリに対する需要) が低い場合にも使用されます。The page file is used even if physical memory pressure (that is, demand for physical memory) is low. 最初に物理メモリの圧迫度が高まったときに、オペレーティング システムでは、データを格納するための領域の確保が必要となり、物理メモリのデータの一部がページ ファイルにバックアップされますが、The first time that physical memory pressure is high, the operating system must make room in physical memory to store data, and it backs up some of the data that is in physical memory to the page file. そのデータは必要になるまでページングされないため、物理メモリの圧迫度が低い状況でページングが発生する可能性もあります。That data is not paged until it's needed, so it's possible to encounter paging in situations where the physical memory pressure is low.

メモリ割り当てMemory allocation

新しいプロセスが初期化されると、ランタイムは連続したアドレス空間領域をそのプロセスのために予約します。When you initialize a new process, the runtime reserves a contiguous region of address space for the process. この予約済みのアドレス空間をマネージド ヒープと呼びます。This reserved address space is called the managed heap. マネージド ヒープは、ヒープ内で次のオブジェクトを割り当てるアドレスへのポインターを管理します。The managed heap maintains a pointer to the address where the next object in the heap will be allocated. 初期状態では、このポインターはマネージド ヒープのベース アドレスに設定されます。Initially, this pointer is set to the managed heap's base address. すべての参照型は、マネージド ヒープ上に割り当てられます。All reference types are allocated on the managed heap. アプリケーションが最初の参照型を作成すると、マネージド ヒープのベース アドレスの位置にその型のメモリが割り当てられます。When an application creates the first reference type, memory is allocated for the type at the base address of the managed heap. アプリケーションが次のオブジェクトを作成すると、ガベージ コレクターは、アドレス空間で最初のオブジェクトの直後のメモリをそのオブジェクトに割り当てます。When the application creates the next object, the garbage collector allocates memory for it in the address space immediately following the first object. ガベージ コレクターは、使用できるアドレス空間がある限り、この方法で新しいオブジェクトにアドレス空間を割り当てていきます。As long as address space is available, the garbage collector continues to allocate space for new objects in this manner.

マネージド ヒープからのメモリ割り当ては、アンマネージド メモリ割り当てよりも高速に処理されます。Allocating memory from the managed heap is faster than unmanaged memory allocation. ランタイムはポインターに値を加算することによってオブジェクトにメモリを割り当てるため、これは、スタックからのメモリ割り当てとほとんど同じ速度になります。Because the runtime allocates memory for an object by adding a value to a pointer, it's almost as fast as allocating memory from the stack. また、連続して割り当てられた複数の新規オブジェクトは、マネージド ヒープに連続して格納されるため、アプリケーションからそれらのオブジェクトに高速でアクセスできます。In addition, because new objects that are allocated consecutively are stored contiguously in the managed heap, an application can access the objects quickly.

メモリの解放Memory release

ガベージ コレクターの最適化エンジンは、現在の割り当て状況に基づいて、ガベージ コレクションの実行に最適な時期を判断します。The garbage collector's optimizing engine determines the best time to perform a collection based on the allocations being made. ガベージ コレクターは、ガベージ コレクションを実行するときに、アプリケーションが使用しなくなったオブジェクトのメモリを解放します。When the garbage collector performs a collection, it releases the memory for objects that are no longer being used by the application. 使用されなくなったオブジェクトを判断するために、アプリケーションの "ルート" を調べます。It determines which objects are no longer being used by examining the application's roots. アプリケーションのルートには、静的フィールド、スレッドのスタック上のローカル変数とパラメーター、CPU レジスタなどが含まれています。An application's roots include static fields, local variables and parameters on a thread's stack, and CPU registers. 各ルートは、マネージド ヒープ上のオブジェクトを参照しているか、または null に設定されています。Each root either refers to an object on the managed heap or is set to null. ガベージ コレクターは、ジャスト イン タイム (JIT) コンパイラとランタイムが管理している、アクティブなルートのリストにアクセスします。The garbage collector has access to the list of active roots that the just-in-time (JIT) compiler and the runtime maintain. ガベージ コレクターは、このリストを使用して、ルートから到達できるすべてのオブジェクトを含むグラフを作成します。Using this list, the garbage collector creates a graph that contains all the objects that are reachable from the roots.

このグラフに含まれないオブジェクトは、アプリケーションのルートからは到達できません。Objects that are not in the graph are unreachable from the application's roots. ガベージ コレクターは、到達できないオブジェクトをガベージであると判断し、それらに割り当てられたメモリを解放します。The garbage collector considers unreachable objects garbage and releases the memory allocated for them. ガベージ コレクション中に、ガベージ コレクターはマネージド ヒープを調べ、到達できないオブジェクトが占有しているアドレス空間ブロックを検索します。During a collection, the garbage collector examines the managed heap, looking for the blocks of address space occupied by unreachable objects. 到達できないオブジェクトを検出すると、それらのオブジェクトに割り当てられていたアドレス空間ブロックを解放し、メモリ コピー機能を使用して、到達できるオブジェクトのメモリを圧縮します。As it discovers each unreachable object, it uses a memory-copying function to compact the reachable objects in memory, freeing up the blocks of address spaces allocated to unreachable objects. 到達できるオブジェクトのメモリを圧縮した後で、ガベージ コレクターは、アプリケーションのルートがそれらのオブジェクトの新しい位置を指すようにポインターを修正します。Once the memory for the reachable objects has been compacted, the garbage collector makes the necessary pointer corrections so that the application's roots point to the objects in their new locations. また、マネージド ヒープのポインターも、最後の到達できるオブジェクトの後を指すように修正します。It also positions the managed heap's pointer after the last reachable object.

メモリが圧縮されるのは、コレクション中に、大量の到達できないオブジェクトが検出された場合だけです。Memory is compacted only if a collection discovers a significant number of unreachable objects. マネージド ヒープ内のすべてのオブジェクトがごみではないと判断された場合は、メモリを圧縮する必要がありません。If all the objects in the managed heap survive a collection, then there is no need for memory compaction.

パフォーマンスを向上させるために、ランタイムは、大きいオブジェクトのメモリは独立したヒープに割り当てます。To improve performance, the runtime allocates memory for large objects in a separate heap. ガベージ コレクターは、これらの大きいオブジェクトのメモリを自動的に解放します。The garbage collector automatically releases the memory for large objects. ただし、メモリ内で大きいオブジェクトを移動するのを避けるため、通常このメモリは圧縮されません。However, to avoid moving large objects in memory, this memory is usually not compacted.

ガベージ コレクションの条件Conditions for a garbage collection

ガベージ コレクションは、次のいずれかの条件に当てはまる場合に発生します。Garbage collection occurs when one of the following conditions is true:

  • システムの物理メモリが少ない場合。The system has low physical memory. OS からのメモリ不足通知またはホストによって示されたメモリ不足のいずれかによって検出されます。This is detected by either the low memory notification from the OS or low memory as indicated by the host.

  • マネージド ヒープで割り当てられたオブジェクトによって使用されているメモリが、許容されるしきい値を超える場合。The memory that's used by allocated objects on the managed heap surpasses an acceptable threshold. このしきい値は、プロセスの進行に合わせて絶えず調整されます。This threshold is continuously adjusted as the process runs.

  • GC.Collect メソッドが呼び出されます。The GC.Collect method is called. ほとんどの場合、ガベージ コレクターは継続して実行されるため、このメソッドを呼び出す必要はありません。In almost all cases, you don't have to call this method, because the garbage collector runs continuously. このメソッドは、主に特別な状況やテストで使用されます。This method is primarily used for unique situations and testing.

マネージド ヒープThe managed heap

ガベージ コレクターは、CLR によって初期化された後、オブジェクトを格納および管理するためのメモリのセグメントを割り当てます。After the garbage collector is initialized by the CLR, it allocates a segment of memory to store and manage objects. オペレーティング システムのネイティブ ヒープに対し、このメモリのことをマネージド ヒープと呼びます。This memory is called the managed heap, as opposed to a native heap in the operating system.

マネージド ヒープはマネージド プロセスごとに割り当てられます。There is a managed heap for each managed process. プロセス内のすべてのスレッドは、同じヒープにオブジェクト用のメモリを割り当てます。All threads in the process allocate memory for objects on the same heap.

メモリを予約するために、ガベージ コレクターは Windows VirtualAlloc 関数を呼び出し、マネージド アプリケーション用のメモリのセグメントを一度に 1 つずつ予約します。To reserve memory, the garbage collector calls the Windows VirtualAlloc function and reserves one segment of memory at a time for managed applications. また、ガベージ コレクターは、必要に応じてセグメントを予約したり、Windows VirtualFree 関数を呼び出すことで (オブジェクトのセグメントをクリアしてから) セグメントを解放してオペレーティング システムに戻したりします。The garbage collector also reserves segments, as needed, and releases segments back to the operating system (after clearing them of any objects) by calling the Windows VirtualFree function.

重要

ガベージ コレクターによって割り当てらるセグメントのサイズは実装に固有であり、定期的な更新プログラムによる場合を含め、いつでも変更されることがあります。The size of segments allocated by the garbage collector 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.

ヒープに割り当てられたオブジェクトが少ないほど、ガベージ コレクターの処理も少なくなります。The fewer objects allocated on the heap, the less work the garbage collector has to do. オブジェクトを割り当てるときは、必要以上に切り上げた値を使用しないでください。たとえば、15 バイトしか必要がないときに 32 バイトの配列を割り当てるなどです。When you allocate objects, don't use rounded-up values that exceed your needs, such as allocating an array of 32 bytes when you need only 15 bytes.

ガベージ コレクションがトリガーされると、ガベージ コレクターは、使用されなくなったオブジェクトに占有されているメモリを解放します。When a garbage collection is triggered, the garbage collector reclaims the memory that's occupied by dead objects. この解放プロセスでは、まとめて移動できるように有効なオブジェクトを圧縮し、使用されなくなったスペースを削除することで、ヒープを小さくします。The reclaiming process compacts live objects so that they are moved together, and the dead space is removed, thereby making the heap smaller. これにより、一緒に割り当てられたオブジェクトが同じマネージド ヒープにまとめられ、局所性が保持されます。This ensures that objects that are allocated together stay together on the managed heap to preserve their locality.

ガベージ コレクションの割り込みの動作 (頻度と期間) は、割り当てのボリュームとマネージド ヒープ上の残ったメモリの量によって決まります。The intrusiveness (frequency and duration) of garbage collections is the result of the volume of allocations and the amount of survived memory on the managed heap.

ヒープは、大きなオブジェクト ヒープと小さなオブジェクト ヒープの 2 つを累積したものと見なすことができます。The heap can be considered as the accumulation of two heaps: the large object heap and the small object heap. 大きなオブジェクト ヒープには、85,000 バイトを超えるオブジェクト (通常は配列) が格納されます。The large object heap contains objects that are 85,000 bytes and larger, which are usually arrays. インスタンス オブジェクトが極端に大きくなることはほとんどありません。It's rare for an instance object to be extremely large.

ヒント

オブジェクトのしきい値サイズを構成すれば、大きなオブジェクト ヒープに移ることができます。You can configure the threshold size for objects to go on the large object heap.

ジェネレーションGenerations

GC アルゴリズムは、次のよういないくつかの考慮事項に基づいています。The GC algorithm is based on several considerations:

  • マネージド ヒープ全体よりも、マネージド ヒープの一部のメモリを圧縮する方が高速です。It's faster to compact the memory for a portion of the managed heap than for the entire managed heap.
  • オブジェクトが新しいほどその存続期間は短く、オブジェクトが古いほど存続期間は長くなります。Newer objects have shorter lifetimes and older objects have longer lifetimes.
  • 新しいオブジェクトは相互に関連し、アプリケーションからほぼ同時にアクセスされる傾向があります。Newer objects tend to be related to each other and accessed by the application around the same time.

ガベージ コレクションは主に、有効期間が短いオブジェクトを解放する場合に発生します。Garbage collection primarily occurs with the reclamation of short-lived objects. ガベージ コレクターのパフォーマンスを最適化するために、マネージド ヒープは 0、1、および 2 の 3 つのジェネレーションに分割されます。そのため、有効期間が長いオブジェクトと短いオブジェクトを別々に処理できます。To optimize the performance of the garbage collector, the managed heap is divided into three generations, 0, 1, and 2, so it can handle long-lived and short-lived objects separately. ガベージ コレクターは、新しいオブジェクトをジェネレーション 0 に格納します。The garbage collector stores new objects in generation 0. アプリケーションの有効期間の初期に作成され、ガベージ コレクションでごみではないと判断されたオブジェクトは昇格してジェネレーション 1 とジェネレーション 2 に格納されます。Objects created early in the application's lifetime that survive collections are promoted and stored in generations 1 and 2. マネージド ヒープの一部を圧縮する方がヒープ全体を圧縮するよりも高速であるため、この手法では、ガベージ コレクターがコレクションを実行するたびにマネージド ヒープ全体のメモリを解放するのではなく、特定のジェネレーションのメモリだけを解放できるようにします。Because it's faster to compact a portion of the managed heap than the entire heap, this scheme allows the garbage collector to release the memory in a specific generation rather than release the memory for the entire managed heap each time it performs a collection.

  • ジェネレーション 0Generation 0. これは一番最初のジェネレーションで、有効期間が短いオブジェクトが格納されます。This is the youngest generation and contains short-lived objects. 有効期間が短いオブジェクトには、たとえば、テンポラリ変数などがあります。An example of a short-lived object is a temporary variable. ガベージ コレクションは、このジェネレーションで最も頻繁に発生します。Garbage collection occurs most frequently in this generation.

    新しく割り当てられたオブジェクトにより、新しいオブジェクトが生成されます。また、新しく割り当てられたオブジェクトは暗黙的にジェネレーション 0 コレクションになります。Newly allocated objects form a new generation of objects and are implicitly generation 0 collections. ただし、大きなオブジェクトであれば、大きなオブジェクト ヒープ (LOH) に移されます。これは、"ジェネレーション 3" と呼ばれることもあります。However, if they are large objects, they go on the large object heap (LOH), which is sometimes referred to as generation 3. ジェネレーション 3 は、ジェネレーション 2 の一部として論理的に収集される、物理的なジェネレーションです。Generation 3 is a physical generation that's logically collected as part of generation 2.

    ジェネレーション 0 では、ほとんどのオブジェクトがガベージ コレクションで解放され、次のジェネレーションには残りません。Most objects are reclaimed for garbage collection in generation 0 and don't survive to the next generation.

    ジェネレーション 0 がいっぱいになったときにアプリケーションが新しいオブジェクトを作成しようとすると、ガベージ コレクターは、そのオブジェクト用のアドレス空間を解放するためにコレクションを実行します。If an application attempts to create a new object when generation 0 is full, the garbage collector performs a collection in an attempt to free address space for the object. まず、ガベージ コレクターは、マネージド ヒープ内の全オブジェクトではなく、ジェネレーション 0 のオブジェクトだけを調べます。The garbage collector starts by examining the objects in generation 0 rather than all objects in the managed heap. 多くの場合、ジェネレーション 0 のコレクションを行うだけで、アプリケーションが新しいオブジェクトの作成を続行するために十分なメモリを解放できます。A collection of generation 0 alone often reclaims enough memory to enable the application to continue creating new objects.

  • ジェネレーション 1Generation 1. このジェネレーションには有効期間が短いオブジェクトが格納されます。有効期間が短いオブジェクトと有効期間が長いオブジェクトの間のバッファーとして機能します。This generation contains short-lived objects and serves as a buffer between short-lived objects and long-lived objects.

    ガベージ コレクターは、ジェネレーション 0 のコレクションを実行した後で、到達できるオブジェクトのメモリを圧縮し、それらをジェネレーション 1 に昇格します。After the garbage collector performs a collection of generation 0, it compacts the memory for the reachable objects and promotes them to generation 1. 一般にガベージ コレクションでごみだと判断されなかったオブジェクトの存続期間は長いので、これらのオブジェクトを上位のジェネレーションに昇格させるのは有効です。Because objects that survive collections tend to have longer lifetimes, it makes sense to promote them to a higher generation. ガベージ コレクターがジェネレーション 0 のコレクションを実行するたびに、ジェネレーション 1 と 2 のオブジェクトを再び調べる必要がなくなります。The garbage collector doesn't have to reexamine the objects in generations 1 and 2 each time it performs a collection of generation 0.

    ジェネレーション 0 のコレクションを行うだけでは、アプリケーションが新しいオブジェクトを作成するために必要なメモリを確保できない場合、ガベージ コレクターはジェネレーション 1、ジェネレーション 2 の順にコレクションを実行できます。If a collection of generation 0 does not reclaim enough memory for the application to create a new object, the garbage collector can perform a collection of generation 1, then generation 2. ガベージ コレクションでごみだと判断されなかったジェネレーション 1 のオブジェクトは、ジェネレーション 2 に昇格します。Objects in generation 1 that survive collections are promoted to generation 2.

  • ジェネレーション 2Generation 2. このジェネレーションには、有効期間が長いオブジェクトが格納されます。This generation contains long-lived objects. 有効期間が長いオブジェクトには、たとえば、プロセスの存続期間を通じて有効な静的データを含むサーバー アプリケーションのオブジェクトなどがあります。An example of a long-lived object is an object in a server application that contains static data that's live for the duration of the process.

    コレクションで解放されなかったジェネレーション 2 のオブジェクトは、その後のコレクションで到達不能であると判断されるまで、ジェネレーション 2 に残ります。Objects in generation 2 that survive a collection remain in generation 2 until they are determined to be unreachable in a future collection.

    大きなオブジェクト ヒープ ("ジェネレーション 3" と呼ばれることもあります) 上のオブジェクトは、ジェネレーション 2 でも収集されます。Objects on the large object heap (which is sometimes referred to as generation 3) are also collected in generation 2.

ガベージ コレクションは、条件に応じて特定のジェネレーションで発生します。Garbage collections occur on specific generations as conditions warrant. ジェネレーションのコレクションでは、そのジェネレーションとそれよりも前のすべてのジェネレーションのオブジェクトがコレクションの対象になります。Collecting a generation means collecting objects in that generation and all its younger generations. ジェネレーション 2 のガベージ コレクションは、すべてのジェネレーションのオブジェクト (つまり、マネージド ヒープのすべてのオブジェクト) を解放することから、フル ガベージ コレクションとも呼ばれます。A generation 2 garbage collection is also known as a full garbage collection, because it reclaims objects in all generations (that is, all objects in the managed heap).

存続と昇格Survival and promotions

ガベージ コレクションで解放されなかったオブジェクトは残存オブジェクトと呼ばれ、次のジェネレーションに昇格されます。Objects that are not reclaimed in a garbage collection are known as survivors and are promoted to the next generation:

  • ジェネレーション 0 のガベージ コレクションで解放されなかったオブジェクトは、ジェネレーション 1 に昇格します。Objects that survive a generation 0 garbage collection are promoted to generation 1.
  • ジェネレーション 1 のガベージ コレクションで解放されなかったオブジェクトは、ジェネレーション 2 に昇格します。Objects that survive a generation 1 garbage collection are promoted to generation 2.
  • ジェネレーション 2 のガベージコレクションで解放されなかったオブジェクトは、ジェネレーション 2 に残ります。Objects that survive a generation 2 garbage collection remain in generation 2.

ジェネレーションでごみではないと判断される割合が高いことがガベージ コレクターで検出されると、そのジェネレーションに対する割り当てのしきい値が高くなります。When the garbage collector detects that the survival rate is high in a generation, it increases the threshold of allocations for that generation. 次のジェネレーションで十分なサイズの解放されたメモリが受け取られます。The next collection gets a substantial size of reclaimed memory. CLR では、ガベージ コレクションを遅延させることでアプリケーションのワーキング セットが大きくなりすぎないようにすることと、ガベージ コレクションの実行頻度が多すぎないようにすることに注意して、それらの 2 つの優先事項のバランスを絶えず調整します。The CLR continually balances two priorities: not letting an application's working set get too large by delaying garbage collection and not letting the garbage collection run too frequently.

短期のジェネレーションとセグメントEphemeral generations and segments

ジェネレーション 0 および 1 のオブジェクトは有効期間が短いことから、それらのジェネレーションのことを "短期ジェネレーション" と呼びます。Because objects in generations 0 and 1 are short-lived, these generations are known as the ephemeral generations.

短期ジェネレーションは、短期セグメントと呼ばれるメモリ セグメントに割り当てられます。Ephemeral generations are allocated in the memory segment that's known as the ephemeral segment. ガベージ コレクターによって新しいセグメントが取得されると、いずれも新しい短期セグメントになり、ジェネレーション 0 のガベージ コレクションで残ったオブジェクトが格納されます。Each new segment acquired by the garbage collector becomes the new ephemeral segment and contains the objects that survived a generation 0 garbage collection. 古い短期セグメントは新しいジェネレーション 2 のセグメントになります。The old ephemeral segment becomes the new generation 2 segment.

短期セグメントのサイズは、システムが 32 ビットと 64 ビットのどちらであるか、および実行されているガベージ コレクターの種類 (ワークステーションの GC またはサーバーの GC) に応じて異なります。The size of the ephemeral segment varies depending on whether a system is 32-bit or 64-bit and on the type of garbage collector it is running (workstation or server GC). 次の表は、短期セグメントの既定のサイズを示しています。The following table shows the default sizes of the ephemeral segment.

ワークステーションの GC またはサーバーの GCWorkstation/server GC 32 ビット32-bit 64 ビット64-bit
ワークステーションの GCWorkstation GC 16 MB16 MB 256 MB256 MB
サーバーの GCServer GC 64 MB64 MB 4 GB4 GB
サーバーの GC (論理 CPU が 4 個以上の場合)Server GC with > 4 logical CPUs 32 MB32 MB 2 GB2 GB
サーバーの GC (論理 CPU が 8 個以上の場合)Server GC with > 8 logical CPUs 16 MB16 MB 1 GB1 GB

短期セグメントには、ジェネレーション 2 のオブジェクトも含めることができます。The ephemeral segment can include generation 2 objects. ジェネレーション 2 のオブジェクトでは複数のセグメントを使用できます (プロセスでの必要に応じてメモリが許容できる限りいくつでも使用できます)。Generation 2 objects can use multiple segments (as many as your process requires and memory allows for).

短期ガベージ コレクションによって解放されるメモリの量は、短期セグメントのサイズまでに限られます。The amount of freed memory from an ephemeral garbage collection is limited to the size of the ephemeral segment. 解放されるメモリの量は、使用されなくなったオブジェクトに占有されていた領域に比例します。The amount of memory that is freed is proportional to the space that was occupied by the dead objects.

ガベージ コレクションの実行時の動作What happens during a garbage collection

ガベージ コレクションには次のフェーズがあります。A garbage collection has the following phases:

  • マーキング フェーズ。有効なすべてのオブジェクトを探し、そのリストを作成します。A marking phase that finds and creates a list of all live objects.

  • 再配置フェーズ。圧縮するオブジェクトへの参照を更新します。A relocating phase that updates the references to the objects that will be compacted.

  • 圧縮フェーズ。使用されなくなったオブジェクトに占有されている領域を解放し、残ったオブジェクトを圧縮します。A compacting phase that reclaims the space occupied by the dead objects and compacts the surviving objects. 圧縮フェーズでは、ガベージ コレクションで残ったオブジェクトをセグメントの後ろに移動します。The compacting phase moves objects that have survived a garbage collection toward the older end of the segment.

    ジェネレーション 2 のコレクションでは複数のセグメントを占有できるため、ジェネレーション 2 に昇格されたオブジェクトはより古いセグメントに移動できます。Because generation 2 collections can occupy multiple segments, objects that are promoted into generation 2 can be moved into an older segment. ジェネレーション 1 とジェネレーション 2 の残存オブジェクトは、どちらもジェネレーション 2 に昇格されるため、別のセグメントに移動できます。Both generation 1 and generation 2 survivors can be moved to a different segment, because they are promoted to generation 2.

    通常、大きなオブジェクト ヒープ (LOH) は圧縮されません。これは、大きなオブジェクトをコピーするとパフォーマンスが低下するためです。Ordinarily, the large object heap (LOH) is not compacted, because copying large objects imposes a performance penalty. ただし、.NET Core と .NET Framework 4.5.1 以降では、GCSettings.LargeObjectHeapCompactionMode プロパティを使用して、大きなオブジェクト ヒープを必要に応じて圧縮できます。However, in .NET Core and in .NET Framework 4.5.1 and later, you can use the GCSettings.LargeObjectHeapCompactionMode property to compact the large object heap on demand. また、LOH は、次のいずれかを指定することでハード上限が設定されるとき、自動的に圧縮されます。In addition, the LOH is automatically compacted when a hard limit is set by specifying either:

ガベージ コレクターは、次の情報に基づいてオブジェクトが有効かどうかを判断します。The garbage collector uses the following information to determine whether objects are live:

  • スタック ルートStack roots. Just-In-Time (JIT) コンパイラとスタック ウォーカーによって提供されるスタック変数。Stack variables provided by the just-in-time (JIT) compiler and stack walker. JIT の最適化では、スタック変数がガベージ コレクターに報告されるコードの領域が延長または短縮される可能性があります。JIT optimizations can lengthen or shorten regions of code within which stack variables are reported to the garbage collector.

  • ガベージ コレクション ハンドルGarbage collection handles. マネージド オブジェクトを参照するハンドル。これらのハンドルは、ユーザー コードまたは共通言語ランタイムで割り当てることができます。Handles that point to managed objects and that can be allocated by user code or by the common language runtime.

  • 静的データStatic data. 他のオブジェクトを参照している可能性があるアプリケーション ドメインの静的オブジェクト。Static objects in application domains that could be referencing other objects. 静的オブジェクトはそれぞれのアプリケーション ドメインで追跡されます。Each application domain keeps track of its static objects.

ガベージ コレクションが開始される前に、そのガベージ コレクションをトリガーしたスレッドを除くすべてのマネージド スレッドが中断されます。Before a garbage collection starts, all managed threads are suspended except for the thread that triggered the garbage collection.

次の図は、ガベージ コレクションを発生させて他のスレッドの中断を引き起こすスレッドを示しています。The following illustration shows a thread that triggers a garbage collection and causes the other threads to be suspended.

スレッドでガベージ コレクションをトリガーする場合

アンマネージ リソースUnmanaged resources

アプリケーションで作成されるオブジェクトの大部分については、ガベージ コレクションによって、必要なメモリ管理タスクを自動的に実行できます。For most of the objects that your application creates, you can rely on garbage collection to automatically perform the necessary memory management tasks. しかし、アンマネージ リソースでは、明示的なクリーンアップが必要です。However, unmanaged resources require explicit cleanup. 最も一般的な種類のアンマネージ リソースは、ファイル ハンドル、ウィンドウ ハンドル、ネットワーク接続などのオペレーティング システム リソースをラップしたオブジェクトです。The most common type of unmanaged resource is an object that wraps an operating system resource, such as a file handle, window handle, or network connection. ガベージ コレクターは、アンマネージ リソースをカプセル化するマネージド オブジェクトの存続期間を追跡することはできますが、そのリソースのクリーンアップ方法については具体的な情報を持っていません。Although the garbage collector is able to track the lifetime of a managed object that encapsulates an unmanaged resource, it doesn't have specific knowledge about how to clean up the resource.

アンマネージ リソースをカプセル化するオブジェクトを作成する場合は、そのアンマネージ リソースをクリーンアップするために必要なコードをパブリックな Dispose メソッドという形で提供することをお勧めします。When you create an object that encapsulates an unmanaged resource, it's recommended that you provide the necessary code to clean up the unmanaged resource in a public Dispose method. Dispose メソッドを提供すると、ユーザーがオブジェクトを使い終わったときに、そのオブジェクトのメモリを明示的に解放できます。By providing a Dispose method, you enable users of your object to explicitly free its memory when they are finished with the object. アンマネージ リソースをカプセル化するオブジェクトを使用する場合は、必要に応じて Dispose を呼び出すようにしてください。When you use an object that encapsulates an unmanaged resource, make sure to call Dispose as necessary.

また、使用する型のコンシューマーが Dispose の呼び出しを忘れた場合に、アンマネージ リソースを解放する手段を用意する必要があります。You must also provide a way for your unmanaged resources to be released in case a consumer of your type forgets to call Dispose. セーフ ハンドルを使用してアンマネージ リソースをラップするか、Object.Finalize() メソッドをオーバーライドできます。You can either use a safe handle to wrap the unmanaged resource, or override the Object.Finalize() method.

アンマネージ リソースのクリーンアップの詳細については、「アンマネージ リソースのクリーンアップ」を参照してください。For more information about cleaning up unmanaged resources, see Clean up unmanaged resources.

関連項目See also