왜 Large Object Heap이고 우리가 관심을 갖는 이유는 무엇입니까?


105

세대 및 대형 개체 힙에 대해 읽었습니다. 하지만 여전히 큰 개체 힙을 갖는 것의 중요성 (또는 이점)이 무엇인지 이해하지 못합니다.

CLR이 대규모 개체를 저장하기 위해 2 세대 (Gen0 및 Gen1에 대한 임계 값이 작은 경우 큰 개체를 처리 할 수 ​​있다는 점을 고려)에 의존했다면 성능 또는 메모리 측면에서 무엇이 잘못되었을 수 있습니까?


6
.NET 디자이너에게 두 가지 질문이 있습니다. 1. OutOfMemoryException이 발생하기 전에 LOH 조각 모음이 호출되지 않는 이유는 무엇입니까? 2.이없는 이유는 LOH 객체가 함께 체류에 대한 친 화성이 (대형은 처음에 힙의 끝에 작은 선호)
야곱 브루

답변:


195

가비지 컬렉션은 참조되지 않은 개체를 제거 할뿐만 아니라 힙을 압축 합니다. 이것은 매우 중요한 최적화입니다. 메모리 사용을 더 효율적으로 만드는 것이 아니라 (사용하지 않는 구멍이 없음) 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 속성 압축을 지원 합니다. 결과를 조심하십시오.


3
@Hans Passant, x64 시스템에 대해 설명해 주시겠습니까?이 문제가 완전히 사라 졌다는 의미입니까?
Johnny_D

LOH의 일부 구현 세부 사항은 의미가 있지만 일부는 저를 당혹스럽게합니다. 예를 들어, 많은 대형 객체가 생성되고 폐기 되는 경우 Gen0 컬렉션의 단편적인 것보다 Gen2 컬렉션에서 한꺼번에 삭제하는 것이 일반적으로 바람직 할 수 있지만, 예를 들어 22,000 개 문자열의 배열을 생성하고 폐기하는 경우 외부 참조가 없습니다. Gen0 및 Gen1 컬렉션이 배열에 대한 참조가 있는지 여부에 관계없이 모든 22,000 문자열에 "라이브"태그를 지정하면 어떤 이점이 있습니까?
supercat

6
물론 조각화 문제는 x64에서도 동일합니다. 서버 프로세스가 시작되기까지 며칠 밖에 걸리지 않습니다.
Lothar

1
음, 아니, 절대로 3 자릿수를 과소 평가하지 마십시오. 4 테라 바이트 힙을 가비지 수집하는 데 걸리는 시간은 그에 가까워지기 오래 전에 발견하는 것을 피할 수 없습니다.
Hans Passant

2
@HansPassant "4 테라 바이트 힙을 가비지 수집하는 데 걸리는 시간은 그에 가까워지기 오래 전에 발견하는 것을 피할 수없는 일입니다."
relative_random

9

개체의 크기가 고정 된 값 (.NET 1의 경우 85000 바이트)보다 크면 CLR은이를 Large Object Heap에 넣습니다. 이는 다음을 최적화합니다.

  1. 개체 할당 (작은 개체는 큰 개체와 혼합되지 않음)
  2. 가비지 수집 (LOH는 전체 GC에서만 수집 됨)
  3. 메모리 조각 모음 (LOH는 거의 압축 되지 않음)

9

SOH (Small Object Heap)와 LOH (Large Object Heap)의 근본적인 차이점은 이 기사에서 설명하는 것처럼 SOH의 메모리는 수집 될 때 압축되지만 LOH는 압축되지 않는다는 것 입니다. 큰 개체를 압축하는 데 많은 비용이 듭니다. 기사의 예와 마찬가지로 메모리에서 바이트를 이동하려면 2 사이클이 필요하고 2GHz 컴퓨터에서 8MB 개체를 압축하려면 8ms가 필요하며 이는 큰 비용입니다. 큰 개체 (대부분의 경우 배열)가 실제로 매우 일반적이라는 점을 고려할 때 Microsoft가 큰 개체를 메모리에 고정하고 LOH를 제안하는 이유라고 생각합니다.

BTW, 이 게시물 에 따르면 LOH는 일반적으로 메모리 조각 문제를 생성하지 않습니다.


1
대량의 데이터를 관리 대상 개체에로드하면 일반적으로 LOH를 압축하는 데 드는 8ms 비용이 줄어 듭니다. 실제로 대부분의 빅 데이터 애플리케이션에서 LOH 비용은 나머지 애플리케이션 성능에 비해 사소합니다.
Shiv

3

원칙은 프로세스가 수명이 짧은 대형 개체를 많이 생성하여 CLR이 일반 힙과 다른 일정으로 GC를 실행하는 별도의 힙에 대형 개체를 할당 할 가능성이 거의 없다는 것입니다. http://msdn.microsoft.com/en-us/magazine/cc534993.aspx


또한 2 세대와 같이 큰 개체를 장착하면 메모리를 압축하는 데 오랜 시간이 걸리기 때문에 성능이 저하 될 수 있습니다. 현재 LOH는 성능상의 이유로 압축되지 않습니다.
Christopher Currens

GC가 잘 처리하지 못하기 때문에 디자인이 나쁘다고 생각합니다.
CodesInChaos

@CodeInChaos는 분명히 몇 가지가 있습니다 4.5 .NET에서 오는 개선
Christian.K

1
@CodeInChaos : 시스템이 수명이 짧은 LOH 개체에서 메모리를 회수하기 전에 gen2 컬렉션이 나올 때까지 기다리는 것이 합리적 일 수 있지만, LOH 개체 (및 해당 개체가 보유한 개체를 선언하는 성능상의 이점은 볼 수 없습니다. 참조) gen0 및 gen1 컬렉션 동안 무조건 라이브. 그러한 가정으로 가능한 최적화가 있습니까?
supercat

@supercat Myles McDonnell이 언급 한 링크를 보았습니다. 내 이해는 : 1. LOH 수집은 2 세대 GC에서 발생합니다. 2. LOH 컬렉션에는 압축이 포함되지 않습니다 (기사 작성 당시). 대신 죽은 개체를 재사용 가능한 것으로 표시하고 이러한 구멍이 충분히 큰 경우 향후 LOH 할당에 사용됩니다. 포인트 1 때문에 2 세대에 오브젝트가 많으면 2 세대 GC가 느려질 것이라는 점을 고려하면이 경우에는 가능한 한 LOH를 사용하지 않는 것이 좋다고 생각합니다.
robbie 팬

0

저는 CLR에 대한 전문가는 아니지만 큰 개체를위한 전용 힙이 있으면 기존 세대 별 힙의 불필요한 GC 스윕을 방지 할 수 있다고 생각합니다. 큰 개체를 할당하려면 상당한 양의 연속 사용 가능한 메모리 가 필요합니다 . 세대 별 힙에 흩어져있는 "구멍"에서이를 제공하려면 빈번한 압축이 필요합니다 (GC 주기로 만 수행됨).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.