이상한 기분,하지만 내가 직접 답변을하려고합니다 :
정말 내가 얘기하고 이해합니다. 그것에 대한 의견을 좀 주시겠습니까?
매우 큰 개체가 할당되고 해제되는 (루프) 경우 두 플랫폼에서 모두 조각화가 발생합니다. 관리되지 않는 앱의 경우 가상 주소 공간에서 직접 할당됩니다. 보통 작업 배열은 클래스 (C++)로 래핑되어 멋진 짧은 구문, 일부 참조 처리 및 소멸자에 대한 연산자 오버로드를 제공합니다. 범위를 벗어나면 이 즉시 해제됩니다. 그럼에도 불구하고 요청 된 배열은 항상 같은 크기가 아닙니다. 더 큰 배열이 요청되면 동일한 주소 블록을 재사용 할 수 없으므로 시간이 지남에 따라 조각화가 발생할 수 있습니다. 게다가, 블록을 찾는 방법이 없기 때문에 요청 된 어레이 길이를 정확하게 제공합니다. 운영 체제는 첫 번째 블록을 사용합니다.이 블록은 필요한만큼 커졌지만 나중에 예정된 더 큰 배열에 대한 요청을보다 완벽하게 채울 수 있었을지라도 충분히 클 수 있습니다. 어떻게 풀링이 그 상황을 개선 할 수 있었습니까?
작은 요청에 더 큰 배열을 사용하는 것이 상상할 수 있습니다. 클래스는 기본 배열의 실제 길이에서 외부 세계에 필요한 가상 길이로의 전환을 처리합니다. 풀은 OS와는 달리 "길이가 긴 첫 번째 어레이"를 제공하는데 도움이 될 수 있습니다. OS는 항상 정확한 길이를 제공합니다. 가상 주소 공간에 생성되는 구멍이 적기 때문에 조각화를 제한 할 수 있습니다. 반면에 전체 메모리 크기는 증가합니다. 거의 랜덤 한 할당 패턴의 경우, 풀링은 이익을 거의 내지 않을 것이지만 드문 기억 만 먹는다.
쪽에서는 상황이 더 나쁩니다. 우선, 조각화에 대한 두 가지 가능한 대상이 있습니다. 가상 주소 공간 및 관리 대상 대형 오브젝트 힙. 이 경우에는 개별 OS의 개별 집합을 개별적으로 수집해야합니다. 각 seqment는 주로 하나의 배열에 대해서만 사용됩니다 (여기서는 정말 큰 배열을 말합니다). 하나의 배열이 GC에 의해 해제되면 전체 세그먼트가 OS로 반환됩니다. 따라서 LOH에서는 조각화가 문제가되지 않습니다 (참조 : 내 자신의 생각과 VMMap을 사용한 경험적 관찰, 어떤 의견이라도 환영합니다!).
하지만 LOH 세그먼트가 가상 주소 공간에서 할당되기 때문에 관리되지 않는 응용 프로그램과 마찬가지로 조각화가 여기에도 문제가됩니다. 실제로 두 응용 프로그램의 할당 패턴은 OS의 메모리 관리자와 매우 유사해야합니다. (?) 하나의 구별 : 배열은 GC에 의해 동시에 해제됩니다. 그러나 "정말로 큰 배열"은 GC에 많은 압박을 줄 것입니다. 수집이 발생할 때까지 비교적 적은 수의 "정말로 큰 배열"만 동시에 유지 될 수 있습니다. 기본적으로 응용 프로그램은 일반적으로 GC에서 합리적인 시간 (약 5..45 %로 보임)을 소비합니다. 사실 모든 컬렉션이 값 비싼 Gen2 컬렉션이 될 것이고 거의 모든 할당이 이러한 Gen 2 컬렉션으로 귀결 될 것이기 때문입니다.
여기 풀링이 상당히 도움이 될 수 있습니다. 어레이가 OS로 해제되지 않고 풀에 수집되면 즉시을 추가 요청에 사용할 수 있습니다. (이것이 IDisposable이 관리되지 않는 리소스를위한 것이 아닌 이유 중 하나입니다.)프레임 워크/라이브러리는 배열이 초기에 풀에 배치되고 실제로 더 작은 크기가 필요한 경우에 더 큰 배열을 재사용 할 수 있도록하기 만하면됩니다.
숙제입니까? –
나는 그것이 좋겠다고 생각했다. 그러나 우리가 제거 할 수없는 유일한 토론 주제 ... 나는 여기에 가능한 대답에 편견을주고 싶지 않지만 확실하게 생각을 가지고있다. 나는 그것이 확증되거나 반증되기를 희망한다. 또한 컨텍스트에 대한 개요를 얻는 데 도움이되어야합니다. – user492238
대규모 관리 개체의 경우 Afaik 풀링이 매우 중요합니다. 감사합니다. – CodesInChaos