C# 클래스 할당시 메모리 구성 디버깅
디스어셈블링 및 실제 메모리를 디버깅하면서 데이터와 객체를 할당시 어떤 구조로 메모리에 올라가는지와
C#에서 클래스를 할당하면, 힙이 어떻게 동작하는지를 보자
쉽게 보기 위해서 예제는 x86(32bit)로 컴파일되었고 이를 기준으로 설명합니다.
예제로 사용할 모습은 이와 같다.
아무 클래스나 하나 만들고 그 안에 문자열 하나와 int 하나를 선언, 구조체 역시 메모리를 살펴보기 쉽게 int형 두개로 선언했다.
먼저 Case1 메소드를 디버깅해보자
Watch창에서 살펴보면 현재 testObject의 상태를 알 수 있고, '&testObject'로 testObject의 실제 메모리 주소를 볼 수 있다.
C# 문법에서는 직접적인 포인터를 사용하려면 unsafe 옵션을 이용해서 사용 할수 있으나, 이는 그리 권장하는 바가 아니며 간접적으로 포인터를 사용할수 있는데 이는 IntPtr을 이용하는 방법이다.
IntPtr의 경우엔 이후에 더 자세히 다룰 예정이다.
해당 메모리 주소로 가서 직접 살펴보면, 0x02eeb6b8 이라는 메모리 주소을 담고 있다.
이것으로 testObject 자체는 특정 주소를 담고 있는 포인터라는 것을 알 수 있다.
포인터가 가르키는 주소로 가서 살표보면 다음과 같다.
하일라이트된 두 영역이 클래스의 맴버변수들을 담고 있는 위치이다.
SomethingClass는 처음 1개의 string 변수와 두번째 int 값을 하나 가지고 있는데, 처음 앞 4바이트가 string이고 두번째 0값으로만 채워져 있는 4바이트 영역이 int값의 메모리 공간이다.
실제로 이렇게 맴버변수 int fisrt의 값을 1212라고 바꾸면, 메모리상에서 어떤 변화가 생기는지 보자
두번째 하이라이트되어 있던 공간의 값이 0000 04bc의 값으로 바뀌었고, 10진수 1212의 16진수 값은 4bc이므로 정확하게 찾은 메모리 위치가 맞는 것을 확인 할 수 있다.
그렇다면 첫번째 하이라이트였던 string 영역의 값을 분석해보면, 문자열의 저장은 해당 문자열이 존재하는 영역의 주소값을 가지고 있다.
즉 첫번재 하이라이트 4바이트 값은 포인터이다.
해당 포인터를 따라가면 이와 같은데, 하이라이트 해둔 부분이 문자열의 총 길이를 나타낸다.
그리고 그 뒤에가 문자열들이 들어 있다.
문자열들을 보기 편하게 2바이트 소팅을 해서보면 처음 값이 4e로 이는 아스키코드로 대문자 'N'에 해당한다 그 뒤로 i c e가 순차적으로 들어 있다.
간단하게 객체 하나가 할당될때 어떤 일들이 메모리상에서 일어나는지 살펴보았다.
다음 포스팅부턴 IntPtr에 대해서 자세하게 쓸려고 한다.
원래 IntPtr을 설명하기 위해서, 이 글을 썼다.
가비지 컬렉터로부터 가변 힙을 할당 받아, 이를 포인터에 넣어 사용하거나 또는 이미 생성한 객체를 포인터로 받아 조작하는 것들을 앞으로 쓸 예정이다.
'나만의 강의' 카테고리의 다른 글
C# 리플렉션으로 Struct(구조체 / ValueType) 수정(Set) 하기 (0) | 2017.06.19 |
---|---|
게임 프로그래밍 공부 방법(입문) - 프로그래밍 공부, 대체 어떻게 해야 돼? (2) | 2014.05.09 |
[ToolFramewrok] 게임엔진과 툴을 연결하는 구조 1 (0) | 2014.03.26 |
[KGC2012 - 자료공개] WPF와 XBAP으로 만드는 개발툴 (0) | 2013.01.01 |
[자료공개] Boost Function ( 2008년 7월 4일 ) (0) | 2012.02.19 |