자동 메모리 관리 는 관리 되 는 실행 을 수행 하 는 중 에 공용 언어 런타임 에서 제공 되 는 서비스 중 하나 입니다 . Automatic memory management is one of the services that the Common Language Runtime provides during Managed Execution . CLR 의 가비지 수집 기 에서 애플리케이션 의 메모리 할당 과 해제 를 관리 합니다 . The Common Language Runtime ' s garbage collector manages the allocation and release of memory for an application . 즉 , 관리 되 는 애플리케이션 을 개발 할 때 개발자 는 메모리 관리 작업 을 수행 하 기 위해 코드 를 작성 할 필요 가 없 습니다 . For developers , this means that you do not have to write code to perform memory management tasks when you develop managed applications . 자동 메모리 관리 를 사용 하 면 실수 로 개체 비우 기 를 수행 하 지 않 거나 메모리 누수 를 유발 하 거나 또는 이미 비워진 개체 를 찾 기 위해 메모리 에 액세스 하 려는 경우 등 의 일반 적 인 문제 를 해결 할 수 있 습니다 . 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 has already been freed . 이 단원 에서 는 가비지 수집 기 에서 메모리 를 할당 하 고 해제 하 는 방법 에 대해 설명 합니다 . This section describes how the garbage collector allocates and releases memory . 
 메모리 할당 Allocating Memory 
 사용 자 가 새 프로세스 를 시작 하 면 런타임 에서 는 인접 한 주소 공간 영역 을 이 프로세스 에 예약 합니다 . 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 is 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 very quickly . 
 메모리 해제 Releasing Memory 
 가비지 수집 기 의 최적화 엔진 은 수행 중 인 할당 에 따라 수집 을 수행 하 기 에 가장 적합 한 시간 을 결정 합니다 . 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 . 모든 애플리케이션 에 는 여러 개 의 루트 가 있 습니다 . Every application has a set of roots . 각 루트 는 관리 되 는 힙 에 있 는 개체 를 참조 하 거나 Null 로 설정 됩니다 . Each root either refers to an object on the managed heap or is set to null . 애플리케이션 루트 에 는 정적 필드 , 스레드 스택 의 지역 변수 와 매개 변수 및 CPU 레지스터 가 포함 되 어 있 습니다 . An application ' s roots include static fields , local variables and parameters on a thread ' s stack , and CPU registers . 가비지 수집 기 는 JIT ( Just - In - Time ) 컴파일러 와 런타임 에서 관리 하 는 활성 루트 목록 에 액세스 할 수 있 습니다 . 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 , it examines an application ' s roots , and in the process 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 will release 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 . 수집 을 수행 하 는 동안 연결 할 수 없 는 개체 의 수 가 엄청나 게 발견 되 는 경우 에 만 메모리 를 압축 한다는 점 에 주목 합니다 . Note that 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 not compacted . 
 세대 및 성능 Generations and Performance 
 가비지 수집 기 의 성능 을 최적 화 하 기 위해 관리 되 는 힙 은 0 세대 , 1 세대 및 2 세대 의 3 개 세대 로 나뉩니다 . To optimize the performance of the garbage collector , the managed heap is divided into three generations : 0 , 1 , and 2 . 런타임 의 가비지 수집 알고리즘 은 컴퓨터 소프트웨어 업계 의 가비지 수집 체계 실험 을 통해 밝혀진 일반 사실 을 기반 으로 하 고 있 습니다 . The runtime ' s garbage collection algorithm is based on several generalizations that the computer software industry has discovered to be true by experimenting with garbage collection schemes . 첫째 로 , 가비지 수집 기 는 관리 되 는 전체 힙 보다 관리 되 는 일부 힙 에서 더 빠르 게 메모리 를 압축 할 수 있 습니다 . First , it is faster to compact the memory for a portion of the managed heap than for the entire managed heap . 둘째 로 , 개체 가 새로 울 수록 수명 은 더 짧 아 지 고 개체 가 오래 될수록 수명 은 더 길 어 집니다 . Secondly , newer objects will have shorter lifetimes and older objects will have longer lifetimes . 마지막 으로 , 새로운 개체 일수록 서로 연결 되 는 경향 이 있 어서 애플리케이션 에서 거의 동시 에 액세스 됩니다 . Lastly , newer objects tend to be related to each other and accessed by the application around the same time . 
 런타임 가비지 수집 기 는 새 개체 를 0 세대 에 저장 합니다 . The runtime ' s 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 . 개체 승격 과정 은 이 단원 의 마지막 부분 에서 설명 하 고 있 습니다 . The process of object promotion is described later in this topic . 전체 힙 보다 일부 관리 되 는 힙 을 압축 하 는 것 이 더 빠르 기 때문 에 가비지 수집 기 는 수집 을 수행 할 때 마다 이 체계 를 사용 하 여 전체 관리 되 는 힙 에서 메모리 를 해제 하 는 대신 특정 세대 에서 메모리 를 해제 할 수 있 습니다 . Because it is 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 . 
 실제로 가비지 수집 기 는 세대 0 이 가득 차면 수집 을 수행 합니다 . In reality , the garbage collector performs a collection when generation 0 is full . 애플리케이션 에서 새 개체 를 만들 려고 할 때 세대 0 이 가득 찬 경우 , 가비지 수집 기 에서 는 개체 할당 할 주소 공간 이 세대 0 에 존재 하 지 않 음 을 감지 합니다 . If an application attempts to create a new object when generation 0 is full , the garbage collector discovers that there is no address space remaining in generation 0 to allocate for the object . 그러면 가비지 수집 기 는 이 개체 를 위해 세대 0 에서 주소 공간 을 비우 기 위해 수집 을 수행 합니다 . The garbage collector performs a collection in an attempt to free address space in generation 0 for the object . 가비지 수집 기 는 관리 되 는 힙 에서 모든 개체 를 검사 하 는 대신 먼저 세대 0 에서 개체 를 검사 합니다 . The garbage collector starts by examining the objects in generation 0 rather than all objects in the managed heap . 이 방식 은 가장 효율 적 인 방식 입니다 . 왜냐하면 새 개체 의 수명 은 짧 은 성향 이 있 으며 수집 이 수행 되 면 세대 0 의 상당수 개체 는 더 이상 애플리케이션 에서 사용 되 지 않 을 것 이 기 때문 입니다 . This is the most efficient approach , because new objects tend to have short lifetimes , and it is expected that many of the objects in generation 0 will no longer be in use by the application when a collection is performed . 또한 , 세대 0 에 만 컬렉션 을 수행 하 더라도 애플리케이션 에서 새 개체 를 계속 만들 수 있 는 충분 한 메모리 를 확보 하 기 도 합니다 . In addition , a collection of generation 0 alone often reclaims enough memory to allow the application to continue creating new objects . 
 가비지 수집 기 에서 는 0 세대 컬렉션 을 수행 한 후 앞서 의 메모리 해제 에서 설명 한 대로 연결 할 수 있 는 개체 의 메모리 를 압축 합니다 . After the garbage collector performs a collection of generation 0 , it compacts the memory for the reachable objects as explained in Releasing Memory earlier in this topic . 그런 다음 가비지 컬렉션 기 는 이 개체 를 승격 시켜서 이 부분 의 관리 되 는 힙 을 세대 1 로 간주 합니다 . The garbage collector then promotes these objects and considers this portion of the managed heap 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 에서 개체 를 다시 검사 할 필요 가 없 습니다 . As a result , the garbage collector does not have to reexamine the objects in generations 1 and 2 each time it performs a collection of generation 0 . 
 가비지 수집 기 는 세대 0 에 처음 으로 수집 을 수행 한 다음 연결 할 수 있 는 개체 들 을 세대 1 로 승격 시키 지만 , 아직 도 관리 되 는 힙 에 남 아 있 는 개체 들 은 세대 0 으로 간주 합니다 . After the garbage collector performs its first collection of generation 0 and promotes the reachable objects to generation 1 , it considers the remainder of the managed heap generation 0 . 가비지 수집 기 는 세대 0 이 가득 차 거나 다른 수집 을 수행 할 필요 가 있 을 때 까지 세대 0 에서 새 개체 에 대한 메모리 할당 을 계속 합니다 . It continues to allocate memory for new objects in generation 0 until generation 0 is full and it is necessary to perform another collection . 이 시점 에서 가비지 수집 기 의 최적화 엔진 은 이전 세대 에서 개체 를 검사 할 필요 가 있 는지 를 결정 합니다 . At this point , the garbage collector ' s optimizing engine determines whether it is necessary to examine the objects in older generations . 예 를 들 어 , 세대 0 에서 수집 을 수행 했 음 에 도 불구 하 고 애플리케이션 에서 새 개체 를 성공 적 으로 만드 는 데 필요 한 충분 한 메모리 를 확보 할 수 없 는 경우 , 가비지 수집 기 는 세대 1 에서 세대 2 의 순서 로 수집 을 수행 할 수 있 습니다 . For example , if a collection of generation 0 does not reclaim enough memory for the application to successfully complete its attempt to create a new object , the garbage collector can perform a collection of generation 1 , then generation 2 . 여기 에서 도 충분 한 메모리 를 확보 할 수 없 다면 , 가비지 수집 기 는 세대 2 , 1 , 0 의 순서 로 수집 을 수행 할 수 있 습니다 . If this does not reclaim enough memory , the garbage collector can perform a collection of generations 2 , 1 , and 0 . 각 수집 이 완료 되 면 가비지 수집 기 는 세대 0 에 있 는 연결 할 수 있 는 개체 를 압축 하 여 세대 1 로 승격 시킵니다 . After each collection , the garbage collector compacts the reachable objects in generation 0 and promotes them to generation 1 . 또한 , 수집 이 완료 된 후 에 세대 1 에 존재 하 는 개체 를 세대 2 로 승격 시킵니다 . Objects in generation 1 that survive collections are promoted to generation 2 . 가비지 수집 기 는 세 가지 세대 만 을 지원 합니다 . 따라서 수집 이 완료 된 후 에 세대 2 에 존재 하 는 개체 는 상위 세대 로 승격 시킬 없 으므로 , 다음 수집 에서 연결 할 수 없 는 개체 로 결정 될 때 까지 세대 2 에 보관 됩니다 . Because the garbage collector supports only three generations , objects in generation 2 that survive a collection remain in generation 2 until they are determined to be unreachable in a future collection . 
 관리 되 지 않 는 리소스 의 메모리 할당 해제 Releasing Memory for Unmanaged Resources 
 가비지 수집 기 는 사용 자 애플리케이션 에서 만들 어 지 는 대부분 의 개체 에 대해 메모리 관리 작업 을 자동 으로 수행 할 수 있 습니다 . For the majority of the objects that your application creates , you can rely on the garbage collector 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 does not have specific knowledge about how to clean up the resource . 관리 되 지 않 는 리소스 를 캡슐 화 해 주 는 개체 를 만드 는 경우 관리 되 지 않 는 리소스 를 정리 하 는 데 필요 한 코드 를 공용 Dispose 메 서 드 에 제공 하 는 것 이 좋 습니다 . When you create an object that encapsulates an unmanaged resource , it is 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 , you should be aware of Dispose and call it as necessary . 관리 되 지 않 는 리소스 정리 및 Dispose 를 구현 하 는 디자인 패턴 예제 에 대해서 는 가비지 수집 을 참조 하 세요 . For more information about cleaning up unmanaged resources and an example of a design pattern for implementing Dispose , see Garbage Collection .