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분
정성태

... 166  167  168  169  170  171  172  [173]  174  175  176  177  178  179  180  ...
NoWriterDateCnt.TitleFile(s)
712정성태4/28/200929953오류 유형: 78. Windows Vista/2008에서의 MSXML4.cab 파일 배포 문제
711정성태4/27/200929768개발 환경 구성: 43. Hyper-V VHD 파일 크기 확장하는 방법
710정성태4/26/200930185.NET Framework: 133. CallbackOnCollectedDelegate was detected [4]파일 다운로드1
709정성태4/24/200926438개발 환경 구성: 42. Windows Vista SP1에서 사용 가능한 Hyper-V 관리 도구
708정성태4/23/200931330.NET Framework: 132. ClickOnce 배포를 명령행 수작업 구성파일 다운로드1
707정성태4/22/200930793개발 환경 구성: 41. Hyper-V에 Linux 설치 - SUSE Linux Enterprise Server 11
706정성태4/21/200926688.NET Framework: 131. ClickOnce - 그룹화시켜 다운로드파일 다운로드1
705정성태4/20/200922244개발 환경 구성: 40. TFS2008 SP1의 DBTier에 SQL Server 2008 SP1 설치 [1]
704정성태4/19/200922210개발 환경 구성: 39. Together 2007 SP1 설치
702정성태4/18/200933650.NET Framework: 130. Infragistics - Tabbed MDI WPF 응용 프로그램파일 다운로드1
701정성태4/17/200928407Windows: 44. bootsect 오류 - Access is denied.
700정성태4/17/200931509.NET Framework: 129. Infragistics WPF 컨트롤 사용 [1]
699정성태4/16/200929876.NET Framework: 128. 이벤트 멤버의 명시적 구현파일 다운로드1
696정성태4/12/200929202오류 유형: 77. RDP 연결이 되지 않는 경우. [1]
693정성태4/9/200923876오류 유형: 76. "Client found response content type of '', but expected 'text/xml'. The request failed with an empty response.No Reports".
692정성태4/8/200936772.NET Framework: 127. ClickOnce로 ActiveX를 같이 배포하는 방법 [2]파일 다운로드1
690정성태4/5/200924436오류 유형: 75. Event Viewer - The data is invalid (13)
688정성태4/5/200930453VS.NET IDE: 60. Output 경로에 매크로 상수 사용하는 방법 [1]
687정성태4/5/200924582.NET Framework: 126. Composite Application Guidance for WPF and Silverlight
689정성태4/5/200924596    답변글 .NET Framework: 126.1. CAG - 빌드 환경 구성파일 다운로드1
691정성태4/6/200924279    답변글 .NET Framework: 126.2. CAG - Shell 띄우기파일 다운로드1
695정성태4/10/200926068    답변글 .NET Framework: 126.3. CAG - 간단한 유형의 모듈 제작파일 다운로드1
703정성태4/18/200925001        답변글 .NET Framework: 126.6. CAG - Tabbed MDI Shell 적용파일 다운로드1
697정성태4/13/200929286    답변글 .NET Framework: 126.4. CAG - Unity 컨테이너 사용 [1]파일 다운로드1
698정성태4/15/200928473    답변글 .NET Framework: 126.5. CAG에 MVVM 패턴 적용 (1) [2]파일 다운로드1
686정성태4/4/200950096웹: 11. IE 8 - TabProcGrowth 레지스트리 키 [2]
... 166  167  168  169  170  171  172  [173]  174  175  176  177  178  179  180  ...