programing

.net 개체의 크기 확인

shortcode 2021. 1. 18. 08:24
반응형

.net 개체의 크기 확인


내 개체가 얼마나 많은 메모리가 Large Object Heap (85,000 바이트 이상)에서 끝나는 지 확인하기 위해 얼마나 많은 메모리를 사용하는지 알아 보려고합니다.

각 객체에 대한 모든 참조 유형 등에 대해 int에 4, long에 8, 4 (또는 64 비트 인 경우 8)를 추가하는 것만 큼 간단합니까, 아니면 메서드, 속성 등에 대한 오버 헤드가 있습니까?


실제 개체의 크기에는 참조하는 개체의 크기가 포함되지 않는다는 것을 잊지 마십시오.

큰 개체 힙에 올 수있는 유일한 것은 배열과 문자열입니다. 다른 개체는 그 자체로 상대적으로 작은 경향이 있습니다. 10 개의 참조 유형 변수 (x86에서 각각 4 바이트)와 10 개의 GUID (각각 16 바이트)가있는 객체조차도 약 208 바이트 만 차지합니다 (유형 참조 및 동기화 블록에 약간의 오버 헤드가 있음).

마찬가지로 배열의 크기에 대해 생각할 때 요소 유형이 참조 유형이면 배열 자체를 계산 하는 참조 의 크기 일 뿐이라는 것을 잊지 마십시오 . 즉, 20,000 개의 요소가있는 배열이 있더라도 더 많은 데이터를 참조하더라도 배열 객체 자체의 크기는 80K (x86에서)가 약간 넘습니다.


개체의 크기를 확인하려면 다음 단계를 따르십시오.

1) Visual Studio (2010) 프로젝트 속성-> 디버그 탭-> 관리되지 않는 코드 디버깅 사용으로 이동합니다.

2) Visual Studio 디버그 메뉴-> 옵션 및 설정-> 디버깅-> 기호로 이동합니다.

3) Microsoft Symbol Server를 활성화하고 기본값을 그대로 둡니다 (기호 다운로드가 시작될 수 있음).

4) 코드에 중단 점을 설정하고 디버깅을 시작합니다 (F5).

5) 디버그-> Windows-> 직접 실행 창을 엽니 다.

6) .load sos.dll (Son of Strike) 입력

7)! DumpHeap -type MyClass (크기를 찾으려는 객체)를 입력하십시오.

8) 출력에서 ​​객체의 주소를 찾습니다. 즉 (00a8197c)

주소 MT 크기 00a8197c 00955124 36

9) 다음으로! ObjSize 00a8197c

10) 간다-> sizeof (00a8197c) = 12 (0x48) 바이트 (MyClass)


가능하다면-직렬화하세요!

Dim myObjectSize As Long

Dim ms As New IO.MemoryStream
Dim bf As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
bf.Serialize(ms, myObject)
myObjectSize = ms.Position

고급 .NET 디버깅 영역에 들어갑니다. John Robins 디버깅 책 부터 시작하십시오 .

Sos.dll (.NET 배포의 일부) 및 Sosex.dll 확장 과 함께 WinDBG사용 합니다. 이러한 도구를 사용하면 애플리케이션이 실행될 때 어떤 일이 발생하는지 실제로 확인할 수 있습니다. 위에서 언급 한 질문에 대한 답을 찾을 수 있습니다.

(또 다른 권장 사항은 공유 소스 CLI 2.0 , 일명 Rotor 2 를 설치 하여 내부에서 무슨 일이 일어나는지 확인하는 것입니다.)


Gomes의 방법이 단순화되었습니다.

  1. Visual Studio (2010) 프로젝트 속성-> 디버그 탭-> 관리되지 않는 코드 디버깅 사용으로 이동합니다.

  2. 코드에 중단 점을 설정하고 디버깅을 시작합니다 (F5).

  3. 디버그-> Windows-> 직접 실행 창을 엽니 다.

  4. .load sos 입력

  5. (myObject를 개체 이름으로 대체)

? String.Format ( "{0 : x}", Integer.Parse (System.Runtime.InteropServices.GCHandle.InternalAddrOfPinnedObject (System.Runtime.InteropServices.GCHandle.Alloc ( myObject ) .GetHandleValue ()). ToString ())-4 )

   6. 결과를! ObjSize의 매개 변수로 사용

참조 : SOS.DLL, 개체 주소 및 Visual Studio 디버거 소개

예 (라는 개체를 찾고 있음 tbl) :

.load sos
extension C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll loaded
? string.Format("{0:x}",Integer.Parse(System.Runtime.InteropServices.GCHandle.InternalAddrOfPinnedObject(System.Runtime.InteropServices.GCHandle.Alloc(tbl).GetHandleValue()).ToString())-4)
"27ccb18"
!ObjSize 27ccb18
PDB symbol for clr.dll not loaded
sizeof(027ccb18) =       154504 (     0x25b88) bytes (System.Data.DataTable)

거대한 값 유형 또는 인스턴스 유형 (예 : 수천 개의 필드)이 아니라면 걱정해야 할 유일한 유형은 큰 배열 또는 문자열입니다. 물론 배열의 크기를 알아 내려면 요소 크기를 알아야합니다.

.NET (현재)은 네이티브 컴파일러가 유형을 정렬하는 것과 거의 동일한 방식으로 유형을 정렬합니다. 기본 유형에는 일반적으로 크기에 가장 가까운 2의 반올림 적분 제곱 인 자연스러운 정렬이 있습니다.

Single, Int32, UInt32 - 4
IntPtr, UIntPtr, pointers, references  - 4 on 32-bit, 8 on 64-bit
Double, Int64, UInt64 - 8
Char, Int16, UInt16   - 2
Byte, SByte           - 1

유형을 어셈블 할 때 컴파일러는 지정된 유형의 모든 필드가 해당 유형과 일치하는 경계에 정렬 된 인스턴스 내에서 시작 오프셋을 갖도록합니다 (명시 적 레이아웃이 사용되지 않는다고 가정).

User-defined types themselves have an alignment, which is calculated as the highest alignment of any of their field types. The type's size is extended if necessary to make the size of the type aligned too.

But of course, all reference types are still only IntPtr.Size in size and alignment, so the size of reference type will not affect arrays of that type.

Note that the CLR may choose, at its discretion, to layout types differently than described above, maybe to increase cache locality or reduce padding required by alignment.


As an estimate (in 2017) you can debug into your application, set a breakpoint before your dictionary comes to live, take a "Memory Usage Snapshot" (Tab: Memory Usage under Diagnostic Tools) , fill your dictionary and get another snapshot - not exact put a good gestimate.

ReferenceURL : https://stackoverflow.com/questions/324053/find-out-the-size-of-a-net-object

반응형