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

... 76  77  78  79  80  81  82  83  84  85  [86]  87  88  89  90  ...
NoWriterDateCnt.TitleFile(s)
11786정성태11/29/201818667오류 유형: 505. OpenGL.NET 예제 실행 시 "Managed Debugging Assistant 'CallbackOnCollectedDelegate'" 예외 발생
11785정성태11/21/201820995디버깅 기술: 120. windbg 분석 사례 - ODP.NET 사용 시 Finalizer에서 System.AccessViolationException 예외 발생으로 인한 비정상 종료
11784정성태11/18/201820260Graphics: 32. .NET으로 구현하는 OpenGL (7), (8) - Matrices and Uniform Variables, Model, View & Projection Matrices파일 다운로드1
11783정성태11/18/201818390오류 유형: 504. 윈도우 환경에서 docker가 설치된 컴퓨터 간의 ping IP 주소 풀이 오류
11782정성태11/18/201817485Windows: 152. 윈도우 10에서 사라진 "Adapters and Bindings" 네트워크 우선순위 조정 기능 - 두 번째 이야기
11781정성태11/17/201820861개발 환경 구성: 422. SFML.NET 라이브러리 설정 방법 [1]파일 다운로드1
11780정성태11/17/201821954오류 유형: 503. vcpkg install bzip2 빌드 에러 - "Error: Building package bzip2:x86-windows failed with: BUILD_FAILED"
11779정성태11/17/201822801개발 환경 구성: 421. vcpkg 업데이트 [1]
11778정성태11/14/201820098.NET Framework: 803. UWP 앱에서 한 컴퓨터(localhost, 127.0.0.1) 내에서의 소켓 연결
11777정성태11/13/201820563오류 유형: 502. Your project does not reference "..." framework. Add a reference to "..." in the "TargetFrameworks" property of your project file and then re-run NuGet restore.
11776정성태11/13/201818612.NET Framework: 802. Windows에 로그인한 계정이 마이크로소프트의 계정인지, 로컬 계정인지 알아내는 방법
11775정성태11/13/201820401Graphics: 31. .NET으로 구현하는 OpenGL (6) - Texturing파일 다운로드1
11774정성태11/8/201818837Graphics: 30. .NET으로 구현하는 OpenGL (4), (5) - Shader파일 다운로드1
11773정성태11/7/201818519Graphics: 29. .NET으로 구현하는 OpenGL (3) - Index Buffer파일 다운로드1
11772정성태11/6/201820488Graphics: 28. .NET으로 구현하는 OpenGL (2) - VAO, VBO파일 다운로드1
11771정성태11/5/201819480사물인터넷: 56. Audio Jack 커넥터의 IR 적외선 송신기 - 두 번째 이야기 [1]
11770정성태11/5/201827902Graphics: 27. .NET으로 구현하는 OpenGL (1) - OpenGL.Net 라이브러리 [3]파일 다운로드1
11769정성태11/5/201818875오류 유형: 501. 프로젝트 msbuild Publish 후 connectionStrings의 문자열이 $(ReplacableToken_...)로 바뀌는 문제
11768정성태11/2/201819349.NET Framework: 801. SOIL(Simple OpenGL Image Library) - Native DLL 및 .NET DLL 제공
11767정성태11/1/201820249사물인터넷: 55. New NodeMcu v3(ESP8266)의 IR LED (적외선 송신) 제어파일 다운로드1
11766정성태10/31/201822351사물인터넷: 54. 아두이노 환경에서의 JSON 파서(ArduinoJson) 사용법
11765정성태10/26/201819230개발 환경 구성: 420. Visual Studio Code - Arduino Board Manager를 이용한 사용자 정의 보드 선택
11764정성태10/26/201824143개발 환경 구성: 419. MIT 라이선스로 무료 공개된 Detours API 후킹 라이브러리 [2]
11763정성태10/25/201821054사물인터넷: 53. New NodeMcu v3(ESP8266)의 https 통신
11762정성태10/25/201821487사물인터넷: 52. New NodeMCU v3(ESP8266)의 http 통신파일 다운로드1
11761정성태10/25/201821454Graphics: 26. 임의 축을 기반으로 3D 벡터 회전파일 다운로드1
... 76  77  78  79  80  81  82  83  84  85  [86]  87  88  89  90  ...