C# 정적 클래스

CLR via C# 책을 보고 궁금한게 있어 질문글을 올립니다.
2부 6장 타입과 맴버의 기본, [정적 클래스]부분에 궁금한 것이 있습니다.

  1. static 클래스가 IL로 봤을 경우 abstract sealed 속성이기 때문에 인스턴스를 할당할 수 없다는 것은 이해했습니다. 추상 클래스는 자체적으로 인스턴스를 가질 수 없기 때문입니다.
    하지만 static int a = 3; 이런식으로 선언하면 IL로 그냥 static Int32가 나타납니다.
    정의로 사용되는 static과 선언으로 사용되는 static이 다르게 동작하는건가요?

  2. 정적 맴버가 인스턴스로 잡히는게 맞다면 최초 메모리할당은 어느시점에 이뤄지나요? 정적클래스로 정의한 객체에 맴버나 메소드를 최초로 사용하면 정적 생성자가 Lazy하게 호출되는 것은 확인했습니다. 생성자가 호출될때 인스턴스로 잡히는지, 아니면 프로그램 시작부터 인스턴스로 잡히는지 궁금합니다.

  3. 1번 질문과 답변이 겹칠 수는 있는데…이 챕터에 "이 키워드는 클래스에 대해서만 적용이 가능하고 값 타입에 대해서는 사용할 수 없는데,"라는 문장이 있는데 뜻이 정적 맴버로는 ‘선언은 가능’ 하지만 '정의는 불가능하다’는 뜻이 맞나요?

  4. 정적으로 선언된 값타입 맴버들이 인스턴스가 할당되는게 맞다면, 그 공간이 stack 영역에 할당되는 것이 맞나요?

정리한다고 정리해봤는데 좋은 질문인지는 잘 모르겠습니다…
요지 파악이 안되신다면 다시 말씀드리겠습니다.

정확한 설명에 감사드립니다. 궁금한 점이 명쾌하게 해결되었습니다.

dimohy님의 멋진 답변에 추가해서 약간 첨언하자면. ^^

문법적으로 전자의 static은 class_modifier에 속하고 후자는 field_modifier에 속한 것으로 다르게 취급됩니다. 마치 new를 힙에 할당하는 예약어로 작용하지만 generic 사용 시에는 같은 new 예약어임에도 generic의 constraint로 취급하는 것과 유사합니다.

닷넷에서 타입 정보가 System.Type의 인스턴스처럼 표현되기는 하지만 엄밀히 GC Heap에 할당되어 있지는 않습니다. 자세한 것은 확인이 필요하지만, 메타데이터에 이미 타입에 대한 명세가 들어 있고 그 메타데이터를 GC 힙에 로딩하지는 않습니다. 다음의 글이 참고가 될 것입니다.

windbg - 닷넷 메모리 덤프에서 정적(static) 필드 값을 조사하는 방법
; 디버깅 기술: 115. windbg - 닷넷 메모리 덤프에서 정적(static) 필드 값을 조사하는 방법

  1. static의 경우 new로 인스턴스화할 수 없다는 걸로 인해 class에서는 필요하지만, struct의 경우에는 (new 없이) 선언 자체로 이미 스택에 할당되므로 abstract로써의 기능을 하지 못합니다. 그래서 아예 막았을 것입니다.

  2. 2번 링크의 글에도 나오지만 GC heap에 배치되지는 않습니다.

3 Likes

아…부가 설명 감사드립니다. CLR via C# 책 1부에서 메타데이터 테이블이 작성되면서 내부 메서드나 필드 속성들 등등의 값이 적히고 외부 참조 어셈블리에 대한 메타데이터테이블이 작성되는 것은 알고 있습니다. 그러면서 동시에 메타데이터에 타입 등록과 별개로 힙에도 타입이 올라가는 줄 알았었는데 그건 아니었군요. 친절한 부가 설명 감사드립니다!!

정성태님이시군요 반갑습니다 ^^ spowner-dimohy 입니다 ^^;