세대 및 대형 개체 힙에 대해 읽었습니다. 하지만 여전히 큰 개체 힙을 갖는 것의 중요성 (또는 이점)이 무엇인지 이해하지 못합니다.
CLR이 대규모 개체를 저장하기 위해 2 세대 (Gen0 및 Gen1에 대한 임계 값이 작은 경우 큰 개체를 처리 할 수 있다는 점을 고려)에 의존했다면 성능 또는 메모리 측면에서 무엇이 잘못되었을 수 있습니까?
세대 및 대형 개체 힙에 대해 읽었습니다. 하지만 여전히 큰 개체 힙을 갖는 것의 중요성 (또는 이점)이 무엇인지 이해하지 못합니다.
CLR이 대규모 개체를 저장하기 위해 2 세대 (Gen0 및 Gen1에 대한 임계 값이 작은 경우 큰 개체를 처리 할 수 있다는 점을 고려)에 의존했다면 성능 또는 메모리 측면에서 무엇이 잘못되었을 수 있습니까?
답변:
가비지 컬렉션은 참조되지 않은 개체를 제거 할뿐만 아니라 힙을 압축 합니다. 이것은 매우 중요한 최적화입니다. 메모리 사용을 더 효율적으로 만드는 것이 아니라 (사용하지 않는 구멍이 없음) CPU 캐시를 훨씬 더 효율적으로 만듭니다. 캐시는 최신 프로세서에서 정말 큰 문제이며 메모리 버스보다 훨씬 빠릅니다.
압축은 단순히 바이트를 복사하여 수행됩니다. 그러나 시간이 걸립니다. 개체가 클수록 개체를 복사하는 데 드는 비용이 CPU 캐시 사용 향상 가능성보다 클 가능성이 높습니다.
그래서 그들은 손익분기 점을 결정하기 위해 많은 벤치 마크를 실행했습니다. 그리고 복사가 더 이상 성능을 향상시키지 않는 컷오프 지점으로 85,000 바이트에 도달했습니다. double 배열에 대한 특별한 예외를 제외하고 배열에 1000 개 이상의 요소가있는 경우 '대형'으로 간주됩니다. 이는 32 비트 코드에 대한 또 다른 최적화입니다. 대형 객체 힙 할당자는 4로만 정렬되는 일반 생성 할당 자와 달리 8로 정렬 된 주소에 메모리를 할당하는 특수 속성을 가지고 있습니다. , 잘못 정렬 된 double을 읽거나 쓰는 것은 매우 비쌉니다. 이상하게도 희소 한 Microsoft 정보는 긴 배열을 언급하지 않으며 그게 무엇인지 확실하지 않습니다.
Fwiw, 큰 개체 힙이 압축되지 않는 것에 대해 많은 프로그래머가 불안해합니다. 이는 사용 가능한 전체 주소 공간의 절반 이상을 소비하는 프로그램을 작성할 때 항상 트리거됩니다. 그 다음에는 메모리 프로파일 러와 같은 도구를 사용하여 사용하지 않는 가상 메모리가 많이 있음에도 프로그램이 폭격을당한 이유를 알아 냈습니다. 이러한 도구는 LOH의 구멍, 이전에 큰 개체가 살았지만 가비지 수집 된 사용되지 않은 메모리 청크를 보여줍니다. 이것은 LOH의 불가피한 가격이며, 구멍은 크기가 같거나 더 작은 개체에 대한 할당에 의해서만 재사용 될 수 있습니다. 실제 문제는 프로그램이 언제든지 모든 가상 메모리 를 사용할 수 있어야한다는 가정입니다 .
64 비트 운영 체제에서 코드를 실행하면 완전히 사라지는 문제. 64 비트 프로세스에는 8TB 의 가상 메모리 주소 공간을 사용할 수 있으며 이는 32 비트 프로세스보다 3 배 더 많습니다. 당신은 구멍이 부족할 수 없습니다.
간단히 말해서 LOH는 코드 실행을 더 효율적으로 만듭니다. 사용 가능한 가상 메모리 주소 공간을 사용하면 효율성이 떨어집니다.
UPDATE, .NET 4.5.1은 이제 LOH, GCSettings.LargeObjectHeapCompactionMode 속성 압축을 지원 합니다. 결과를 조심하십시오.
SOH (Small Object Heap)와 LOH (Large Object Heap)의 근본적인 차이점은 이 기사에서 설명하는 것처럼 SOH의 메모리는 수집 될 때 압축되지만 LOH는 압축되지 않는다는 것 입니다. 큰 개체를 압축하는 데 많은 비용이 듭니다. 기사의 예와 마찬가지로 메모리에서 바이트를 이동하려면 2 사이클이 필요하고 2GHz 컴퓨터에서 8MB 개체를 압축하려면 8ms가 필요하며 이는 큰 비용입니다. 큰 개체 (대부분의 경우 배열)가 실제로 매우 일반적이라는 점을 고려할 때 Microsoft가 큰 개체를 메모리에 고정하고 LOH를 제안하는 이유라고 생각합니다.
BTW, 이 게시물 에 따르면 LOH는 일반적으로 메모리 조각 문제를 생성하지 않습니다.
원칙은 프로세스가 수명이 짧은 대형 개체를 많이 생성하여 CLR이 일반 힙과 다른 일정으로 GC를 실행하는 별도의 힙에 대형 개체를 할당 할 가능성이 거의 없다는 것입니다. http://msdn.microsoft.com/en-us/magazine/cc534993.aspx