2009-08-24 4 views
7

많은 사람들이 혼란 스럽습니다.CLR은 정적 클래스를 어디에 저장합니까?

일반 클래스는 데이터를 힙에 바로 저장합니까? 스택에 대한 참조 (포인터).

스택이 범위를 벗어날 때 다음 번에 가비지 수집기가 실행되어 힙에서 메모리가 제거됩니다.

이제 정적 클래스의 경우 전체 프로그램이 있어야하기 때문에 메모리를 가비지 수집기로 정리할 수 없습니다. 그리고 처음에는 참조를 얻을 수있는 방법이 없습니다.

그래서 우리는 콘솔을 호출합니다. 예를 들어 씁니까? 프로그램은 어디에 참조 번호를 부여합니까 () 정적 클래스에 대한 참조는 어디에 저장됩니까? 아니면 그냥 직접 호출하지만 어떻게?

+4

이 질문에 대해서는 이해할 수 없습니다. "그 가치"와 "그 심판"은 무엇을 의미합니까? –

+0

그는 데이터 멤버와 실행 코드를 분리하는 방법에 대해 이야기하고 있다고 생각합니다. –

+1

다른 문제 중 "그것"입니다. – jason

답변

16

나는 메모리가 메모리에 개최되는 방법함께 살고있는 곳을 와 혼동 클래스 생각합니다. 일반 클래스의 인스턴스를 만들면 해당 인스턴스의 메모리가 힙에 저장됩니다. 이 인스턴스에 대한 참조은 힙의 개체에있을 수 있습니다 (개체의 다른 인스턴스 안에 멤버 변수를 설정 한 경우). 또는 스택 변수 (메서드 내에서 객체에 대한 변수를 선언하거나 함수 호출에 전달한 경우) 또는 전역 루트 목록에있을 수 있습니다 (정적 참조 인 경우 Singleton 참조).

정적 클래스를 인스턴스화 할 수 없습니다. 클래스에 대한 "참조"는 어디에도 없습니다 (유형 정보 제외). 이 메서드는 CLR이 어셈블리를로드 할 때 메모리에로드되는 함수 일뿐입니다. 이 메서드 중 하나를 가리키는 대리자를 만들 수도 있지만이 메서드는 해당 클래스의 인스턴스를 참조하지 않습니다. 이것은 함수에 대한 포인터 일뿐입니다.

예를 들어,이 코드를 보면 :

class ObjectWrapper 
{ 
    Object obj = new Object(); 
} 

static void Main(string[] args) 
{ 
    ObjectWrapper wrapper = new ObjectWrapper(); 
    ... 
} 

메인 메소드는 ObjectWrapper 클래스의 인스턴스를 만듭니다. 이 인스턴스는 힙에 있습니다.

ObjectWrapper 인스턴스 내부에는 힙에있는 Object 클래스의 인스턴스가 있습니다. 이 클래스에 대한 참조는 인스턴스 내부에 있으므로 참조를 "힙에 살기"라고 생각할 수 있습니다.

지금, 다음 코드로이 비교 :

class Singleton 
{ 
    static readonly instance = new Singleton(); 
} 

싱글 톤 개체의 인스턴스가 힙에 살고, 너무. 그러나 참조은 정적 참조입니다. CLR은 전역 또는 "루트"참조 목록에서이를 유지 관리합니다.

지금이 정적 클래스를 보면 :

class ObjectWrapper 
{ 
    Object obj = new Object(); 
} 

static class HelperMethods 
{ 
    static int DoSomethingUseful(ObjectWrapper wrapper1) 
    { 
     ObjectWraper wrapper2 = wrapper1; 
     // code here 
    } 
} 

HelperMethods 정적 클래스입니다. HelperMethods 클래스는 인스턴스화 할 수 없습니다. 이 클래스의 객체는 힙에있을 수 없습니다. 그러나 DoSomethingUseful 메서드에는 스택에있는 ObjectWrapper 클래스의 인스턴스에 대한 참조가 두 개 있습니다. 하나는 전달되고 하나는 메소드 내부에서 선언됩니다.

+0

+1, 세부 사항을 즐겼다. – user7116

+0

"뿌리"에 관해서는 .NET의 GC 알고리즘을 설명하고 뿌리가 GC에서 어떻게 역할 하는지를 설명하는이 기사를 확인하십시오. http://msdn.microsoft.com/en-us/magazine/bb985010.aspx – felideon

+0

이 대답에는 완전히 정확하지 않은 몇 가지 사항이 있습니다. 하나는 '아무 것도 없습니다'라는 문구가 '어디에도 없다'라는 문구가 잘못되었습니다. 모든 유형 (정적 또는 기타)에 대한 참조는 로더 힙에 보관됩니다. 전체 형식 시스템은 형식 및 해당 멤버에 대한 참조와 함께 로더 힙에서 관리됩니다. 또한 '이 클래스는 힙의 메모리를 절대로 소비하지 않습니다.'또한 올바르지 않습니다 ... GC 힙 공간을 사용하지 않지만 로더 힙의 힙 공간을 사용합니다. 단순히 포인터가되는 참조 개념은 잘못된 것입니다 ... CLR은 많은 수준의 간접 지정을 사용합니다. – jrista

6

간단한 답변을 제공하기 위해 정적 클래스는 로더 힙 (Loader Heap)에 저장됩니다.로더 힙은 매우 예측 가능하고 엄격한 성장률을 보이는 특수한 GC가 아닌 치료입니다. .NET 응용 프로그램이 시작되면 실제로 여러 AppDomains가 만들어집니다. 기본 응용 프로그램 도메인 외에도 시스템 네임 스페이스와 mscorelib, 특수 힙 (예 : 로더 힙) 및 CLR 자체가 포함 된 시스템 및 공유 응용 프로그램 도메인이 있습니다. 완전 자세한 설명

은 다음 MSDN 잡지 기사 읽기 : 몇 년 전에서 임에도 불구하고

Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects

을 여전히 적용됩니다. (그러나 .NET 4.0이 많이 변경된 경우 말할 수 없습니다.)

관련 문제