2017-02-10 3 views
0

MemoryMappedViewStream.PointerOffset 속성을 이해하는 데 약간의 문제가 있습니다. 이 간단한 단위 테스트에서 스트림의 PointerOffset은 500000이 되겠지만 41248이라고 예상합니다. 스트림의 길이는 10000이지만 적어도 정확합니다. _fakeDataPath는 1 백만 바이트의 파일입니다.MemoryMappedViewStream.PointerOffset의 값이 잘못되었습니다.

[TestMethod] 
    public void CheckViewHasCorrectOffset() 
    { 
     using (var mmf = MemoryMappedFile.CreateFromFile(_fakeDataPath)) 
     { 
      using (var stream = mmf.CreateViewStream(500000, 10000)) 
      { 
       Assert.AreEqual(500000, stream.PointerOffset); 
      } 
     } 
    } 

단위 테스트 출력은 ...

Assert.AreEqual failed. Expected:<500000>. Actual:<41248> 
+0

에서 [소스] (https://referencesource.microsoft.com/#System.Core/System/IO/MemoryMappedFiles/MemoryMappedView.cs,91bd2847a1fb80e7) 무슨 일이 일어나고 있는지 알 수'PointerOffset'를 전용'MemoryMappedView' 생성자에 전달 된 것을 반환하고, 메서드의 주석에 "extraMemNeeded"라고 전달합니다. "extraMemNeeded는 요청한 뷰가 시작되기 전에 할당하는 추가 메모리의 양입니다." MemoryMappedFile.GetSystemPageAllocationGranularity();': 64k가 일반적입니다 :'50 (ulong) 0000 % (64 * 1024) = 41248 '이다. 아마도 버그 일 수 있습니다. – Quantic

답변

1

CreateViewStream()은 MapViewOfFile() winapi function 주위 .NET 래퍼이다. 이 API의 가장 관련있는 세부 사항은 다음과 같습니다.

높은 오프셋과 낮은 오프셋의 조합은 파일 매핑 내에서 오프셋을 지정해야합니다. 또한 시스템의 메모리 할당 세분성과 일치해야합니다. 즉, 오프셋은 할당 세분성의 배수 여야합니다.

할당 단위는 64K입니다. 또는 다른 방식으로 말하면 기본 API는 지정하는 오프셋이 항상 65536의 배수 여야 함을 요구합니다.

상당히 고통스럽고 .NET 래퍼에서 이러한 제한을 숨기기로 결정했습니다. 쉽게 수행 할 수 있습니다. 네이티브 함수에 다른 오프셋을 전달하면 500000보다 작은 65536의 가장 가까운 배수에서 시작됩니다. 다른 내부 오프셋을 사용하면 효과적으로 500000을 얻을 수 있습니다. 같은 코드 :

Assert.AreEqual(500000 % 65536, stream.PointerOffset); 
+0

'PointerOffset'은 대신'500000 - 500000 % 65536'을 반환해야합니까? 500k 바이트에서 오프셋을 요청할 때 실제로 64k의 배수를 요구해야만합니다. 따라서 실제 오프셋은 [소스 코드] (https : // referencesource)에 표시된 것과 같습니다. microsoft.com/#System.Core/System/IO/MemoryMappedFiles/MemoryMappedView.cs) : 'ulong newOffset = (ulong) offset - extraMemNeeded;'. 뷰는 바이트 458,752에서 시작하지만'PointerOffset'는 41,248을 반환합니다. – Quantic

+0

아니요, newOffset이 PointerOffset의 값이라고 가정합니다. 그렇지 않습니다, 그것은 extraMemNeeded, MemoryMappedView 생성자 호출을보십시오. OP의 게시물은 거의 의심의 여지가 없습니다. –

+1

41,248 (소스의'extraMemNeeded')으로 설정 한 버그가 아닙니까? ['PointerOffset'] (https://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedviewstream.pointeroffset (v = vs.110) .aspx) : " 이 뷰의 시작 위치는 메모리 매핑 된 파일의 시작 부분에서 오프셋됩니다. " 뷰는'newOffset'에서 시작하지만,'extraMemNeeded'를'PointerOffset'에 할당합니다. newOffset *은 PointerOffset이어야하고 대신 extraMemNeeded를 전달하여 망쳐 놨다 고 가정합니다. – Quantic

관련 문제