Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 3개 있습니다.)
(시리즈 글이 8개 있습니다.)
.NET Framework: 268. .NET Array는 왜 12bytes의 기본 메모리를 점유할까?
; https://www.sysnet.pe.kr/2/0/1173

.NET Framework: 269. 일반 참조형의 기본 메모리 소비는 얼마나 될까요?
; https://www.sysnet.pe.kr/2/0/1174

.NET Framework: 270. .NET 참조 개체 인스턴스의 Object Header를 확인하는 방법
; https://www.sysnet.pe.kr/2/0/1175

.NET Framework: 271. C#에서 확인해 보는 관리 힙의 인스턴스 구조
; https://www.sysnet.pe.kr/2/0/1176

.NET Framework: 401. windbg에서 확인해 보는 관리 힙의 인스턴스 구조
; https://www.sysnet.pe.kr/2/0/1559

.NET Framework: 1003. x64 환경에서 참조형의 기본 메모리 소비는 얼마나 될까요?
; https://www.sysnet.pe.kr/2/0/12486

.NET Framework: 1004. C# - GC Heap에 위치한 참조 개체의 주소를 알아내는 방법
; https://www.sysnet.pe.kr/2/0/12487

.NET Framework: 1184. C# - GC Heap에 위치한 참조 개체의 주소를 알아내는 방법 - 두 번째 이야기
; https://www.sysnet.pe.kr/2/0/13017




일반 참조형의 기본 메모리 소비는 얼마나 될까요?

지난번 글을 통해서, 배열과 관련된 인스턴스의 메모리를 살펴보는 방법을 알아봤습니다.

.NET Array는 왜 12bytes의 기본 메모리를 점유할까?
; https://www.sysnet.pe.kr/2/0/1173

배열은 12bytes가 기본소비되는 데요. 그렇다면 일반적인 클래스의 경우에는 얼마나 메모리를 소비할까요?

처음 이 의문이 들었을 때, 저는 간단하게 8bytes라고 생각했습니다. 왜냐하면, ^^ 배열과 비교해서 '요소 수'로 할당된 4bytes가 없어지기 때문입니다. 그런데... 그게 아니더군요. ^^

직접 확인을 해볼까요? 예제를 위해, 코드는 다음과 같이 작성하고,

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Program pg = new Program();
            Thread.Sleep(-1);
        }
    }
}

windbg로 확인하면,

0:004> .loadby sos clr

0:004> !name2ee ConsoleApplication1!ConsoleApplication1.Program
PDB symbol for clr.dll not loaded
Module:      00292e9c
Assembly:    ConsoleApplication1.exe
Token:       02000002
MethodTable: 00293810
EEClass:     00291424
Name:        ConsoleApplication1.Program

0:004> !dumpheap -mt 00293810
 Address       MT     Size
026cbf90 00293810       12     
total 0 objects
Statistics:
      MT    Count    TotalSize Class Name
00293810        1           12 ConsoleApplication1.Program
Total 1 objects

0:004> !do 026cbf90 
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\syswow64\KERNEL32.dll - 
Name:        ConsoleApplication1.Program
MethodTable: 00293810
EEClass:     00291424
Size:        12(0xc) bytes
File:        D:\...\ConsoleApplication1.exe
Fields:
None

0:004> !dumpclass 00291424
Class Name:      ConsoleApplication1.Program
mdToken:         02000002
File:            D:\...\ConsoleApplication1.exe
Parent Class:    72cb3ef8
Module:          00292e9c
Method Table:    00293810
Vtable Slots:    4
Total Method Slots:  5
Class Attributes:    100000  
Transparency:        Critical
NumInstanceFields:   0
NumStaticFields:     0

0:004> dd 026cbf90 
026cbf90  00293810 00000000 00000000 00000000
026cbfa0  00000000 00000000 00000000 00000000

보시는 바와 같이, 배열 타입과 동일하게 12bytes를 소비하고 있습니다. 왜냐하면 빈 객체라고 해도 데이터 공간으로 기본 4바이트를 점유하고 있기 때문입니다. (참고로, 00293810 데이터 앞의 4바이트 위치에는 OBJECT HEADER가 위치하고 있습니다.)

혹시나 싶어서, int (4바이트) 형의 필드를 ConsoleApplication1.Program에 선언하고,

namespace ConsoleApplication1
{
    class Program
    {
        int test = 0xFF;

        static void Main(string[] args)
        {
            Program pg = new Program();
            Thread.Sleep(-1);
        }
    }
}

다시 메모리 값을 확인해 보면 다음과 같이 나옵니다.

0:004> !dumpheap -mt [Program 타입의 MT 값]
 Address       MT     Size
024cbf90 0019381c       12     
total 0 objects
Statistics:
      MT    Count    TotalSize Class Name
0019381c        1           12 ConsoleApplication1.Program
Total 1 objects

0:004> !dumpmt 0019381c
EEClass:      00191428
Module:       00192e9c
Name:         ConsoleApplication1.Program
mdToken:      02000002
File:         D:\...\ConsoleApplication1.exe
BaseSize:        0xc
ComponentSize:   0x0
Slots in VTable: 7
Number of IFaces in IFaceMap: 0

0:004> !dumpclass 00191428
Class Name:      ConsoleApplication1.Program
mdToken:         02000002
File:            D:\...\ConsoleApplication1.exe
Parent Class:    72cb3ef8
Module:          00192e9c
Method Table:    0019381c
Vtable Slots:    4
Total Method Slots:  5
Class Attributes:    100000  
Transparency:        Critical
NumInstanceFields:   1
NumStaticFields:     0
      MT    Field   Offset                 Type VT     Attr    Value Name
72fd28f8  4000001        4         System.Int32  1 instance           test

0:004> dd 024cbf90 
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\syswow64\KERNEL32.dll - 
024cbf90  0019381c 000000ff 00000000 00000000
024cbfa0  00000000 00000000 00000000 00000000

필드를 하나 더 포함하고 있는데도 여전히 12bytes가 소비되고 있습니다. 왜냐하면 필드를 포함하지 않았을 때도 00000000으로 기본 포함되어 있던 영역이 사용되고 있기 때문입니다. 물론 필드 하나를 더 추가하는 순간부터 메모리가 4bytes씩 늘어납니다.

이로써, 그 동안의 이야기를 정리해 보면 아래와 같습니다.

[x86 기준]
0 크기 배열: 12bytes
배열이 아닌 일반 참조형 개체: 12bytes

[x64 기준]
0 크기 배열: 24bytes
배열이 아닌 일반 참조형 개체: 24bytes





[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 7/7/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2011-11-15 03시24분
[Lyn] windbg 의 -mt 가 무슨 의미죠?
[guest]
2011-11-15 07시55분
dumpheap의 옵션으로 사용된 "-mt"는 "MethodTable"을 의미하며, 관리 힙에서 주어진 mt 값에 속하는 개체를 출력해 줍니다.
정성태
2013-12-30 12시17분
windbg에서 확인해 보는 관리 힙의 인스턴스 구조
; http://www.sysnet.pe.kr/2/0/1559
정성태
2017-05-26 02시23분
정성태

... 106  107  108  109  110  [111]  112  113  114  115  116  117  118  119  120  ...
NoWriterDateCnt.TitleFile(s)
11150정성태2/21/201719334.NET Framework: 645. Visual Studio Fakes 기능에서 Shim... 클래스가 생성되지 않는 경우 [5]
11149정성태2/21/201723021오류 유형: 378. A 64-bit test cannot run in a 32-bit process. Specify platform as X64 to force test run in X64 mode on X64 machine.
11148정성태2/20/201721965.NET Framework: 644. AppDomain에 대한 단위 테스트 시 알아야 할 사항
11147정성태2/19/201721203오류 유형: 377. Windows 10에서 Fake 어셈블리를 생성하는 경우 빌드 시 The type or namespace name '...' does not exist in the namespace 컴파일 오류 발생
11146정성태2/19/201719870오류 유형: 376. Error VSP1033: The file '...' does not contain a recognized executable image. [2]
11145정성태2/16/201721341.NET Framework: 643. 작업자 프로세스(w3wp.exe)가 재시작되는 시점을 알 수 있는 방법 - 두 번째 이야기 [4]파일 다운로드1
11144정성태2/6/201724695.NET Framework: 642. C# 개발자를 위한 Win32 DLL export 함수의 호출 규약 (부록 1) - CallingConvention.StdCall, CallingConvention.Cdecl에 상관없이 왜 호출이 잘 될까요?파일 다운로드1
11143정성태2/5/201722093.NET Framework: 641. [Out] 형식의 int * 인자를 가진 함수에 대한 P/Invoke 호출 방법파일 다운로드1
11142정성태2/5/201730101.NET Framework: 640. 닷넷 - 배열 크기의 한계 [2]파일 다운로드1
11141정성태1/31/201724384.NET Framework: 639. C# 개발자를 위한 Win32 DLL export 함수의 호출 규약 (4) - CLR JIT 컴파일러의 P/Invoke 호출 규약 [1]파일 다운로드1
11140정성태1/27/201720139.NET Framework: 638. RSAParameters와 RSA파일 다운로드1
11139정성태1/22/201722822.NET Framework: 637. C# 개발자를 위한 Win32 DLL export 함수의 호출 규약 (3) - x64 환경의 __fastcall과 Name mangling [1]파일 다운로드1
11138정성태1/20/201721099VS.NET IDE: 113. 프로젝트 생성 시부터 "Enable the Visual Studio hosting process" 옵션을 끄는 방법 - 두 번째 이야기 [3]
11137정성태1/20/201719808Windows: 135. AD에 참여한 컴퓨터로 RDP 연결 시 배경 화면을 못 바꾸는 정책
11136정성태1/20/201719000오류 유형: 375. Hyper-V 내에 구성한 Active Directory 환경의 시간 구성 방법 - 두 번째 이야기
11135정성태1/20/201719988Windows: 134. Windows Server 2016의 작업 표시줄에 있는 시계가 사라졌다면? [1]
11134정성태1/20/201727410.NET Framework: 636. System.Threading.Timer를 이용해 타이머 작업을 할 때 유의할 점 [5]파일 다운로드1
11133정성태1/20/201723512.NET Framework: 635. C# 개발자를 위한 Win32 DLL export 함수의 호출 규약 (2) - x86 환경의 __fastcall [1]파일 다운로드1
11132정성태1/19/201735003.NET Framework: 634. C# 개발자를 위한 Win32 DLL export 함수의 호출 규약 (1) - x86 환경에서의 __cdecl, __stdcall에 대한 Name mangling [1]파일 다운로드1
11131정성태1/13/201723958.NET Framework: 633. C# - IL 코드 분석을 위한 팁 [2]
11130정성태1/11/201724460.NET Framework: 632. x86 실행 환경에서 SECURITY_ATTRIBUTES 구조체를 CreateEvent에 전달할 때 예외 발생파일 다운로드1
11129정성태1/11/201728849.NET Framework: 631. async/await에 대한 "There Is No Thread" 글의 부가 설명 [9]파일 다운로드1
11128정성태1/9/201723289.NET Framework: 630. C# - Interlocked.CompareExchange 사용 예제 [3]파일 다운로드1
11127정성태1/8/201722813기타: 63. (개발자를 위한) Visual Studio의 "with MSDN" 라이선스 설명
11126정성태1/7/201727550기타: 62. Edge 웹 브라우저의 즐겨찾기(Favorites)를 편집/백업/복원하는 방법 [1]파일 다운로드1
11125정성태1/7/201724381개발 환경 구성: 310. IIS - appcmd.exe를 이용해 특정 페이지에 클라이언트 측 인증서를 제출하도록 설정하는 방법
... 106  107  108  109  110  [111]  112  113  114  115  116  117  118  119  120  ...