허용되는 대답이 잘못되었습니다. 정렬을 무시합니다. 구조체의 크기는 단순히 멤버의 합계가 아닙니다. 필드 사이의 추가 공간과 구조체의 끝은 프로세서가 필드를 효율적으로 읽고 .NET 메모리 모델에서 제공되는 원 자성 보장을 구현하는 데 필요할 수 있습니다.
DateTimeOffset에 추가로 복잡한 코드입니다. DateTimeOffset 구조체를 작성한 Microsoft 프로그래머는 DateTime 구조체를 복사/붙여 넣기하여 코드를 작성하여 큰 실수를 저지른 것입니다. 하나가 아닌 두 개의 필드가 있기 때문에 DateTimeOffset의 중요한 문제는 역사적인 실수입니다. Sequential 대신 LayoutKind.Auto를 사용합니다. 최적으로 필드를 배치하는 CLR에 여유를 준다 Reference Source
에서 쉽게 볼 32- 비트 모드가 정상적으로 같이 8 바이트 Int64를 정렬되지 것이다 어떤 모드가 실행된다. 그렇지만 4 바이트입니다. 필드 사이에 채우기가 적어지면 크기는 12 바이트입니다.
마찬가지로 64 비트 모드에서 필드를 8로 정렬하는 것이 좋습니다. 필드 사이에 더 많은 패딩이 생성됩니다.
이것을 보는 유일한 방법은 디버거를 사용하는 것입니다. 코드의이 비트를 실행 브레이크 포인트 히트는, 디버그를 사용하는 경우
static void Main(string[] args) {
var arr = new DateTimeOffset[] {
new DateTimeOffset(0x123456789abcdef0, TimeSpan.FromMinutes(60)),
new DateTimeOffset(0x123456789abcdef0, TimeSpan.FromMinutes(60)),
};
System.Diagnostics.Debugger.Break();
}
> 주소 상자에 윈도우> 메모리> 메모리 1 및 유형 &arr[0]
배열의 내용을보고.
0x00000115DC4FBA30 3c 00 00 00 00 00 00 00 f0 76 f8 38 70 56 34 12 <.......ðvø8pV4.
0x00000115DC4FBA40 3c 00 00 00 00 00 00 00 f0 76 f8 38 70 56 34 12 <.......ðvø8pV4.
0x00000115DC4FBA50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
오프셋 필드 (60 = 0x003c)와 날짜 시간 필드를 쉽게 볼 수 있습니다.창 크기를 조정하여 2 가지 요소를 분명하게 만들었으므로 컴퓨터에서 깨끗하게 보이지 않습니다. 그러나 반복 할 때까지 바이트를 계산하면 DateTimeOffset은 16 바이트을 64 비트 모드로 사용합니다.
크기가 32 비트와 64 비트 모드 사이에서 다르다는 사실은 일반적으로 당신을 상당히 걱정해야합니다. 이 버그는 수정해야 할 필요가 전혀 없으며 DateTimeOffset에 대한 합리적인 interop 스토리가 없으며 동일한 관리되지 않는 유형과 일치하지 않습니다. WinRT (일명 UWP)에서 지정된 interop 유형이지만 CLR에 내장 된 언어 프로젝션이 문제를 숨 깁니다.
+1 원래 문제를 해결해 주셔서 감사합니다. 내 웹 응용 프로그램에서이 일을 생각하고 있었지만, 다중 요청이 발생할 수 있으므로 스레드 안전성을 보장 할 수 없습니다. –
어느정도 sz를 높이면 다른 영향에 대한이 트릭의 감도를 줄일 수 있습니다. 그러나이 코드는 일시적으로 메모리 조각을 태 웁니다. 따라서 프로덕션 용도로 이상적이지 않습니다. 그러나 새로운 Azure 인스턴스를 회전시키고 코드를 실행 한 다음 인스턴스를 삭제할 수 있습니다. 어쨌든 한스의 접근 방식은 신뢰할 수있는 정확한 숫자가 필요할 때 훨씬 좋습니다. 그러나, 이것은 새로운 애플리케이션 기능의 메모리 영향을 추측하고자 할 때 사용하는 경향이 있습니다 (대개 온전한 메모리 크기 예측 예측). – Brian