[개발 일기] static 필드 초기화 확인하기
개요
갑자기 static 필드가 언제 생성되고 초기화 되는지 궁금해서 직접 확인해봤습니다.
예전에 강의 들었을 때는 클래스 내에 static 필드가 있을 때
처음 static 필드가 사용되면 그 때 해당하는 클래스 내의 static 필드들이 초기화된다고 이해했습니다.
그래서 일단 코드로 한번 확인해봤습니다.
코드
using System;
class Player
{
public static int Count;
static Player()
{
Console.WriteLine($"정적 생성자 진입: Count = {Count}");
Count = 10;
}
public Player()
{
Console.WriteLine("Player 인스턴스 생성");
}
}
class Program
{
static void Main()
{
Console.WriteLine("Main 시작");
Console.WriteLine($"첫 번째 읽기: {Player.Count}");
Player.Count++;
Console.WriteLine($"두 번째 읽기: {Player.Count}");
}
}
출력 결과

분석하기

해당 정적 생성자 부분에 break를 걸고 디버그를 해봤습니다

보면 첫 번째 읽기에서 Player.Count를 호출하려고 할 때 정적 생성자가 호출되고
Player.Count가 0으로 초기화 된 모습을 볼 수 있습니다


이후 정적 생성자 진입: Count = 0이 출력되고 이후 Count에 10이 대입되는 것을 확인할 수 있습니다
이후 당연히 Count = 10, Count = 11이 출력되는 것을 볼 수 있습니다

추가

검사해보다 새로운 사실을 알게 됐습니다
visual studio에서 디버그를 하는 중 Main 진입 때 break를 걸어봤습니다.
근데..
갑자기 정적 생성자를 호출해버렸습니다
정확한 동작 원리는 잘 모르겠지만, 일단 유추해봤을 때 조사식에 Player.Count라는 변수를 추가해줬는데

이거 때문에 Player.Count라는 변수에 접근해야하기 때문에 정적 생성자를 호출한게 아닌가 싶습니다.

일단 끝까지 실행하면 이렇게 출력결과가 다르게 됩니다
추가 2
그러면 디버그 모드에 따라 출력 값이 달라질 수 있지 않을까? 해서 코드를 다시 작성해봤습니다
코드
using System;
class Player
{
public static int Count;
static Player()
{
Count = Program.InitialCount;
Console.WriteLine($"정적 생성자 실행: Count = {Count}");
}
}
class Program
{
public static int InitialCount;
static void Main()
{
InitialCount = 10; // 여기에 F9로 중단점 설정
Console.WriteLine($"Main에서 읽은 Count = {Player.Count}");
}
}
일단 해당 코드를 실행하면

이렇게 출력됩니다
메인에서 InitialCount에 10을 넣고 이후 Player.Count를 읽을 때 Player 생성자가 호출되고
Count에 Program.InitialCount를 넣어준 값이 출력되기 때문에 10, 10 이 출력됩니다.
그리고 주석 부분에 중단점을 설정하면

이렇게 출력됩니다
여기서 조사식에 Player.Count가 들어있어 정적 생성자가 바로 실행되고
이때 InitialCount의 값도 0이기 때문에 Player.Count가 0으로 초기화됩니다.
이후 Main에서 출력될 때도 0으로 출력되므로 0, 0이 출력됩니다.
느낀점
사실 정말 알고 싶었던 건 static 변수들이 메모리에 언제 생성되는지 알고 싶었는데,
Visual Studio에서 메모리 창은 특정 주소에 현재 들어 있는 바이트만 보여줘서 어렵다고 합니다.
다른 방법을 아시는 분은 댓글 부탁드립니다.. (_ _)
사실 알고 싶었던 것도 해결 못하고, 이 방법으로 알 수 있는 것도 아니여서 약간의 뻘 짓? 이었던 것 같습니다. 허허..
프로그램을 빌드하는 과정 중간에 static변수, 전역변수가 초기화? 생성? 된다고
예전에 학교에서 배웠던 것 같은데 기억이 잘 안나네요..
이 부분은 좀 더 공부를 해봐야겠습니다..


