2010-06-22 1 views
12

16GB RAM이 장착 된 Windows Server 2008 x64에서 .NET 응용 프로그램 실행. 이 애플리케이션은 매우 많은 양의 데이터 (약 64GB)를 가져와 분석하고 한 번에 전체 메모리에 보관해야합니다..NET 가비지 컬렉터 및 x64 가상 메모리

예상되는 내용 : 프로세스 크기가 16GB에서 64GB로 확장됩니다. Windows는 가상 메모리를 사용하여 필요에 따라 디스크에 추가 데이터를 페이징합니다. 이것은 고전적인 가상 메모리 사용 사례입니다.

실제로 보는 내용 : 프로세스 크기는 실제 메모리 크기 (16GB)로 제한됩니다. 응용 프로그램은 시간의 99.8 %를 가비지 수집기에 소비합니다.

응용 프로그램에서 가상 메모리를 사용하지 않는 이유는 무엇입니까? 이 문제는 .NET 가비지 수집기의 구성 또는 Windows x64 가상 메모리 관리자 자체의 구성에 문제가 있습니까? 실제 메모리에 국한되지 않고 가상 메모리를 사용하도록 응용 프로그램을 만들려면 어떻게해야합니까?

감사합니다.

- 브라이언

업데이트 : 당신이 그것을 시도하려는 경우

using System; 

namespace GCTest 
{ 
    class Program 
    { 
     static void Main() 
     { 
      byte[][] arrays = new byte[100000000][]; 
      for (int i = 0; i < arrays.Length; ++i) 
      { 
       arrays[i] = new byte[320]; 
       if (i % 100000 == 0) 
       { 
        Console.WriteLine("{0} arrays allocated", i); 
        System.Threading.Thread.Sleep(100); 
       } 
      } 
     } 
    } 
} 

것은, 64에 대한 구축해야합니다 : 나도 같은 행동을 나타내는 아주 작은 프로그램을 작성했습니다. 시스템에 스트레스를주기 위해 상수를 약간 수정해야 할 수도 있습니다. 내가 보는 행동은 프로세스가 16GB의 크기에 접근함에 따라 문제가 발생한다는 것입니다. 오류 메시지 또는 예외가 발생하지 않습니다. 성능 모니터는 GC의 CPU 시간 비율이 100 %에 도달 함을보고합니다.

이것은 용납되지 않습니까? 가상 메모리 시스템은 어디에 있습니까?

+0

프로세스의 크기를 결정하기 위해 무엇을 사용하고 있습니까? (그냥 쉬운 옵션을 먼저 없애자 :) – Paolo

+0

Windows 작업 관리자에서 "커밋 크기". 또한 "# 전체 커밋 된 바이트"성능 모니터를 사용하여. 나는 물리적 인 작업 세트보다는 프로세스의 가상 메모리 크기를 측정하고 있다고 확신한다. – brianberns

+0

분명히 물어볼 수 있습니까? _ 모든 메모리를 한번에 메모리에로드해야합니까? 다른 접근 방식을 취하고 수동으로 일종의 수동 페이징을 할 수 있습니까? – CodingGorilla

답변

2

대용량 데이터에 대한 참조를 유지하지 않는 것 같습니다. 가비지 수집기는 참조 된 개체를 수집하지 않습니다.

+0

그게 적절하지 않다고 생각합니다. 실제로 아무 데이터도 가비지가 아닙니다. 모두 참조됩니다. 따라서 GC가 메모리를 모을 것으로 기대하지는 않습니다. 프로세스에서 실제 메모리가 부족하여 .NET에서 일부를 비우려고하기 때문에 GC가 100 %의 CPU를 사용하고있는 것처럼 보입니다.그러나 해제해야 할 것이 없습니다. 이상적으로는 프로세스가 가상 메모리를 사용하여 GC에서 모든 시간을 사용하지 않는 (존재하지 않는) 사용하지 않는 개체를 사용하려고하는 대신 확장해야합니다. – brianberns

+0

64 GB의 데이터를 할당했지만 실제로는 16 GB 만 ​​할당 된 경우 나머지는 참조되지 않고 GC로 처리됩니다. 내가 너의 질문을 이해하지 않는 한. –

+0

질문을 이해하지 못했습니다. 64GB의 데이터를 할당하려고 시도하지만 16GB의 데이터 만 할당 한 후에 프로세스가 중단됩니다. 나는 나머지 데이터를 할당 할 수있는 기회를 얻지 못한다. – brianberns

10

페이징 파일이 해당 크기로 확장되도록 구성되어 있는지 확인 했습니까?

업데이트

내가 여기 주어진 예제이 주위에 꽤 연주하고 봤는데 내가 무엇을보고있다.

시스템 : Windows 7 64 비트, 6 채널 RAM, 8 코어.

  1. OS의 다른 스핀들에 추가 페이징 파일이 필요합니다. 이러한 종류의 조사가 사용자의 컴퓨터를 오염시킵니다. 모든 것이 동일한 페이징 파일을 통해 진행되면 상황이 악화됩니다.

  2. GC에서 대용량의 데이터와 대량의 GC 스윕/컬렉션을 비롯하여 실제 메모리 한도에 도달하면 페이지 폴트가 엄청납니다. 필자는 실제 메모리가 너무 많이 소모되면 생성 스윕과 판촉을 트리거하여 많은 양의 페이징 아웃 메모리를 만져서 감동 한 메모리가 페이징 된 메모리와 다른 메모리로 이동하게되는 것으로 추측합니다 강제로. 모든 것이 어지러운 혼란에서 끝납니다. 이것은 Small Object Heap에서 끝나는 많은 수의 수명이 긴 오브젝트를 할당 할 때 필연적 인 것처럼 보입니다.

이제 (같은 청소 및 홍보 문제를 용납하지 않는) 대형 개체 힙에 직접 할당하는 방식으로 객체를 할당이 비교 :

private static void Main() 
{ 
    const int MaxNodeCount = 100000000; 
    const int LargeObjectSize = (85 * 1000); 

    LinkedList<byte[]> list = new LinkedList<byte[]>(); 

    for (long i = 0; i < MaxNodeCount; ++i) 
    { 
     list.AddLast(new byte[LargeObjectSize]); 

     if (i % 100000 == 0) 
     { 
      Console.WriteLine("{0:N0} 'approx' extra bytes allocated.", 
       ((i + 1) * LargeObjectSize)); 
     } 
    } 
} 

를이 예상 예로 작동 가상 메모리가 사용 된 다음 결국 소모됩니다 - 내 환경/구성에서 54GB.

그래서 오래 지속되는 작은 개체를 할당하면 실제 메모리가 모두 소모되었을 때 생성 스윕 및 판촉이 이루어 지므로 결국 GC에서 악의적 인 사이클이 발생합니다. 페이지 파일 죽음의 나선입니다.

나는 뚜렷한 차이를 만들어하지 않는 옵션의 수 \ 구성으로 연주 문제 조사 하다니 업데이트 2

:

  • 은 서버 GC 모드를 강제합니다.
  • 저 지연 GC 구성.
  • GC를 상각하려고 시도하는 강제 GC의 다양한 조합입니다.
  • 최소 \ 최대 프로세스 작업 집합.
+0

아니요, Windows 가상 메모리 관리자가 적어도 16GB를 지난 후 페이징을 자동으로 시작하지 않아야합니까? 물리적 메모리의 양에 의해 제한되는 경우 가상 메모리를 갖는 요지는 무엇입니까? – brianberns

+0

구성 할 가치가 있습니다. 문제는 예기치 않은 정책에서 페이징을 끄는 밝은 불꽃에 이르기까지 다양 할 수 있습니다. –

+0

OK, 페이지 파일을 30GB로 늘렸으나 아무 효과가 없었습니다. NET 가비지 컬렉터가 16GB 이상의 객체를 할당하지 못하게하여 Windows 가상 메모리 시스템에 페이징을 시작할 기회가 없다고 생각합니다. – brianberns