Visual Studio 2022
class 생성
멤버변수 int 하나
public class Test
{
int data_1;
}
public static void Main(string[] args)
{
Test test = new Test();
}
int 하나인데 크기가 24 바이트이다.
int = 4byte 인데 왜 6배나 되는걸까?
=>6개 이상일 때 크기 확인 해보기로함
public class Test
{
public int data_1;
public int data_2;
public int data_3;
public int data_4;
public int data_5;
public int data_6;
}
일단 int 6개로 테스트, 기대 결과는 그대로 24byte
이게 무슨일이지, 40 byte 가 나옴
처음 결과를 기준으로 생각해보면 24 + 16 즉 16 byre가 추가됨.
4(int) * 4(count) 라고 생각해보고 다시 필드를 int * 3으로 테스트
public class Test
{
public int data_1;
public int data_2;
//public int data_3;
//public int data_4;
//public int data_5;
//public int data_6;
}
예상한대로면 처음 결과인 24가 나와야함
결과는 기대한대로 나왔지만 여전히 24라는 크기가 이해가 안감,
혹시나해서 클래스를 인스턴스화 안했을때 한번 확인해봤지만 당연하게 해당 메모리 안잡힘
이번엔 하나씩 필드 늘려가면서 확인해보기로함
int * 4 일때는 동일하게 32
int * 5 부터 40 으로 잡혔음
그럼 그냥 빈 클래스는 얼마로 잡히나 확인했는데
애초에 비어있는 클래스를 인스턴스하면 24 byte 할당됨
여기서 2개씩 int 추가될 때마다 8 byte가 늘어나는데 이 늘어나는 값은 4(int) * 2(count) 맞음
비어있는 클래스가 왜 24 byte의 힙을 차지하는지 파악해보면될듯함
일단 Program 외부에 Test_2 클래스, 내부에는 Test_1 선언 후 비교
public class Test_2 { }
public class Program
{
public class Test_1 { }
public static void Main(string[] args)
{
Test_1 test_1 = new Test_1();
Test_2 test_2 = new Test_2();
}
}
테스트 해본 결과 클래스를 할당하면 기본 크기가 24로 잡히고 이 안에 8byte 까지는 포함시킬 수 있는걸로 보인다.
즉 기본 24 = 16(사용됨) + 8(여유 공간) 이고 크기가 24 byte를 넘을 경우 8byte 단위로 확장되는걸로 파악됨
구글링 해본 결과 내가 원하는 정보를 찾을 수 있었다.
OF MEMORY AND STRING_Jon Sket
본래 글의 취지는 .Net에서 ASCII 문자열의 효율적인 표현에 관한것에 대한 답이다.
위 글에서는 x86과 x64를 모두 비교하고 있는데 이 글에서는 x64를 기준으로 정리한다.
그럼 이제 왜 0byte는 될수없는지 그리고 24byte 중 사용할 수 없는 16byte와 사용 가능한 8byte는 무엇 때문인지 정리한다.
우선 C#에서 모든 타입은 object 타입을 베이스로한다. 그리고 이 object 타입의 크기는 24byte이다.
이 24byte의 크기는 16byte의 오버헤드와 참조를 위한 8byte로 이루어진다.
오버헤드란 처리를 하기 위해 들어가는 간접적인 처리 시간, 메모리 등을 말한다. 즉 C#의 object를 메모리에 유지시키는데 필요한 메모리 양이 16byte이며 .Net의 CLR은 데이터가 없는 object에서 작업할 수 없기 때문에 오버헤드만 가지고는 object를 사용할 수 없고 여유 공간이 필요하며 이 크기가 8byte이다. 따라서 선언될 수 있는 가장 작은 크기의 메모리는 24byte가 된다.
이 중 여유공간인 8byte는 실제 데이터를 저장할 수 있기 때문에 int가 2개 포함된 class역시 24byte였다. 이 8byte는 전체를 사용할 수 있는 공간이기 때문에 1byte로 8를 사용하는것도 가능하다. 그리고 int가 3개가 될때 24byte에서 8byte로 증가했는데 이것은 메모리의 경계인 패딩의 크기가 8byte였기 때문이다.
class 역시 object 타입을 베이스로 하고 있고 빈 class를 인스턴스화 하는것은 object를 생성하는것과 마찬가지이기 때문에 빈 class가 24byte라는것도 이제 납득이 간다.
오버헤드에 대한 내용
overhead - Andrew Hunter
overhead - Stack Overflow
왜 이렇게 많은 공간이 필요한지 또 이 공간은 어떤식으로 사용되는지 궁금한데 이 부분은 더 자세히 찾아봐야 될것같다.
정리
64bit 기준으로
1. 비어있는 class 또한 하나의 object이다. 따라서 24byte 메모리를 차지한다.
2. 이 메모리는 16byte의 내부 데이터 참조형으로 사용되는 오버헤드와 8byte의 여유공간으로 구성된다.
3. 여유공간은 모두 사용이 가능하며 메모리는 8byte의 패딩을 가지고 있다.
'Memo' 카테고리의 다른 글
다국어를 제공하는 방법에 대해서 (0) | 2023.05.10 |
---|