2013-07-31 4 views
4

는 : 랜덤 액세스가있는 경우 40GB의 파일은, 매우 이상한 행동이 :메모리 매핑 된 파일 및 메모리 소비

static void Test() 
    { 
     string fileName = @"d:\map"; 
     long length = new FileInfo(fileName).Length; 
     using (var file = MemoryMappedFile.CreateFromFile(fileName, FileMode.Open, "mapFile", length, MemoryMappedFileAccess.ReadWrite)) 
     { 
      byte* bytePtr = (byte*)0; 
      var view = file.CreateViewAccessor(0, length, MemoryMappedFileAccess.ReadWrite); 
      view.SafeMemoryMappedViewHandle.AcquirePointer(ref bytePtr); 

      long count = (long)(length/sizeof(int)); 
      long sum = 0; 
      long step = count/2000; 

      int* ptr = (int*)&bytePtr[0]; 
      long currentCount = 0 ; 

      Parallel.For(0, count, new ParallelOptions { MaxDegreeOfParallelism = 8 }, (i) => 
      { 
       Interlocked.Add(ref sum, ptr[i]); 
       Interlocked.Increment(ref currentCount) ; 

       if (currentCount % step == 0) 
        Console.Write("\r{0:0.00}%", (100 * currentCount/(float)count)); 
      }); 

      Console.WriteLine(sum); 

      view.Dispose(); 
     } 
    } 

"\ 맵 d는"점을 감안 포인터 "ptr"을 통해.

시스템의 실제 메모리가 완전히 사용되며 모든 작업이 느려지므로이 프로세스를 완료하는 데 2 ​​시간 이상이 걸립니다.

순차적 (및 단일 스레드) 액세스 권한이있는 경우 사용 된 실제 메모리는 1GB가 아니며 프로세스는 약 8 분이 걸립니다.

내 질문은 : 메모리 매핑 된 파일을 사용할 때 "실제"메모리가 사용됩니까? 점령되는 가상 주소 공간뿐만 아니라?

메모리 매핑 된 파일을 사용할 때 실제 메모리 사용량을 이해하려고합니다.

답변

5

메모리 매핑 된 파일은 가상 메모리를 사용합니다. 64 비트 운영 체제에서 RAM을 사용하는 것보다 더 많은 기가 바이트의 VM 공간을 매핑하는 데 문제가 없습니다. 수요 페이지 가상 메모리 운영 체제의 요점은 실행중인 모든 프로세스에 필요한 메모리의 합이 항상 RAM의 양을 크게 초과한다는 것입니다.

RAM에 매핑하는 것이 돈이 들기 때문에 요구 사항 인이 재생됩니다. 프로세서는 프로그램을 중단하고 RAM에 매핑되지 않은 가상 메모리 주소에 액세스하려고 할 때 도움을 요청합니다. 페이지 오류이라고합니다.

40GB 이상의 RAM을 확보하는 데 돈을 쓰지 않았다면 필연적으로 이러한 페이지 오류를 처리하는 OS의 비용을 지불하게됩니다. RAM 페이지를 할당하고 파일의 내용으로 채워야합니다. Perf는 이전에 매핑 된 RAM의 매핑을 해제하고 해당 내용을 파일에 저장해야 할 때 South로 이동합니다. 해제 된 RAM 페이지를 다시 사용하고 적절한 파일 오프셋에서 파일 내용을로드합니다. 아주 사슴, 디스크가 느립니다. "스 래싱"으로 알려진 문제.

메모리를 순차적으로 지정할 때 한 페이지 폴트가 4096 바이트의 순차적 액세스에 적합하며 여행 할 때 디스크 판독기 헤드가 여전히 올바른 위치에있을 확률이 높습니다 페이지 폴트.