programing

정적 필드는 내부적으로 정확히 어떻게 작동합니까?

nasanasas 2020. 12. 27. 11:03
반응형

정적 필드는 내부적으로 정확히 어떻게 작동합니까?


이 질문에 이미 답변이 있습니다.

수업이 있다고합시다.

class Foo
{
    public static bar;
}

네가 얘기 할 때:

new Foo();

메모리에서이 객체를위한 공간이 예약되어 있다고 상상할 수 있습니다.

... 다시 말할 때 :

new Foo(); 

... 이제 객체에 사용할 수있는 다른 공간이 있습니다.

그러나 정적 필드는 정확히 어디에 있습니까?

내가 정말로 배우고 자하는 것은 :

개체에 대한 참조는 참조하는 개체의 동일한 필드를 어떻게 참조합니까?


타입 시스템의 정확한 세부 사항은 구현에 따라 다르지만, 그것이 의존적 이며 신경 쓰지 말아야한다고 말하는 것보다 더 자세히 설명하겠습니다 . Jeffrey Richter의 C # via C #Hanu Kommalapati et al 의 CLR이 런타임 개체만드는 방법 문서 에 따라 Microsoft의 구현 (.NET)에서 대략적으로 어떻게 작동하는지 설명합니다 . ( 원본 MSDN 2005 년 5 월호 ).


수업이 있다고 가정 해 보겠습니다.

class Foo
{
    // Instance fields
    string myBar = "Foobar";
    int myNum;

    // Static fields
    static string bar = "Foobar";
    static int num;
}

Foo myFoo = new Foo();
Type typeOfFoo = typeof(Foo);

인스턴스 필드는 어디에 있습니까?

라고 말할 때마다 new Foo()객체 인스턴스에 공간이 할당되고 초기화되고 생성자가 호출됩니다. 이 인스턴스는 아래 이미지에서 Foo의 인스턴스로 표시됩니다 . 예를 들어 인스턴스에는 클래스의 인스턴스 필드 (이 경우 myBarmyNum) 만 포함되며 힙에 할당 된 객체의 경우 런타임에 사용되는 두 개의 추가 필드 ( Sync block indexType handle)가 포함됩니다. 유형 핸들은 Type인스턴스 유형을 설명 하는 객체에 대한 포인터 입니다.이 경우 유형은 Foo 입니다.

new Foo()다시 말하면 , 유형의 인스턴스 필드를위한 공간을 다시 포함 할 새 공간이 할당됩니다. 보시다시피 인스턴스 필드는 개체 인스턴스 와 연결되어 있습니다.

런타임은 각 인스턴스 필드를 객체 데이터의 시작에서 고정 된 오프셋에 배치합니다. 예를 들어 myBar오프셋 +4에있을 수 있습니다. 인스턴스 필드의 주소는 단순히 개체의 주소에 필드의 오프셋을 더한 것입니다.

정적 필드는 어디에 있습니까?

C # 및 Java의 정적 필드는 개체 인스턴스와 연결되지 않고 유형과 연결됩니다. 클래스, 구조체 및 열거 형이 유형의 예입니다. 유형 당 한 번만 정적 필드의 값을 보유하기 위해 할당 된 일부 공간입니다. Type유형 Type하나의 객체 만 있기 때문에 유형을 설명하는 구조 의 정적 필드에 공간을 할당 하는 것이 좋습니다. 이것은 C # 및 Java에서 취한 접근 방식입니다.

Type오브젝트 1 유형은 런타임에서 로딩 될 때 생성된다. 이 구조에는 런타임이 새 인스턴스를 할당하고, 메서드를 호출하고, 캐스팅을 수행하는 데 필요한 모든 종류의 정보가 포함되어 있습니다. 정적 필드 (이 경우 bar및)를 위한 공간도 포함 num됩니다.

런타임은 각 정적 필드를 유형의 데이터 시작에서 약간의 오프셋에 배치했습니다. 이것은 각 유형마다 다릅니다. 예를 들어 bar오프셋 +64에있을 수 있습니다. 정적 필드의 주소는 Type개체 의 주소에 필드의 오프셋을 더한 것입니다. 유형은 정적으로 알려져 있습니다.

일부 개체 구조 및 해당 관계를 표시합니다.

1 ) Microsoft .NET에서는 MethodTableEEClass 구조 같은 여러 다른 구조가 유형을 설명합니다 .


이것은 완전히 문제의 구현에 달려 있습니다. C # 및 Java의 경우 런타임에서 변수에 대한 메모리를 저장할 위치를 결정할 수 있습니다. C 및 대부분의 컴파일 된 언어의 경우 컴파일러가이 결정을 내립니다.

즉, 실제로는 중요하지 않습니다 . 용도는 사양에 따라 결정되므로 동작이 보장되는 것을 알고있는 변수를 자유롭게 사용할 수 있습니다.


Java의 경우 정적 필드에서 참조하는 객체는 다른 객체와 마찬가지로 힙에 상주 합니다.

힙은 모든 클래스 인스턴스 및 배열에 대한 메모리가 할당되는 런타임 데이터 영역입니다.

The field will be initialised (if the declaration contains an initialization) when the class is loaded, which happens immediately before the first occurrence of any one of the following:

  • an instance of the class is created.
  • a static method declared by the class is invoked.
  • a static field declared by the class is assigned.
  • a static field declared by the class is used and the field is not a constant variable (§4.12.4).

The access to the static field is done via 2 special JVM instructions, getstatic and putstatic. But apart from that distinction, static fields are similar to non static fields.


This varies wildly from language to language, and can even vary wildly from platform to platform...

For example, on the .NET side, static members are "associated" with the governing EEClass definition, which can be a heap-allocated OR a "wherever" allocated member (the C# spec doesn't specify heap/stack behavior, it's an implementation detail of the VM)


There might be exceptions, but for reference types the new-keyword usually creates an object in an internal data structure called "heap". The heap is managed by the CLR (Common Language Runtime). It makes no difference whether you have a static or instance member or a local variable.

The difference between static members and instance members (the ones without the keyword static) is, that static members exist only once per type (class, struct) and instance members exist once per instance (per object).

It is only the reference which is static or not; this distinction does not apply to the referenced object (unless the object is a value type). A static member, an instance member and a local variable can all reference the same object.


Im only familiar with C#, and this is my understanding of it:

Then your program starts, it loads all the related assemblies into an AppDomain. When the assambly is loaded, all static constructors are called, including static fields. They will live in the there, and the only way to unload them, is to unload the AppDomain.


Static members and constants are stored on heap. Unlike objects on heap that can get garbage collection, Static members and constants do stay till Appdomain is torn down, Hence once should be carefull in dealing with static fields


Static variables belong to the class not the object so there is only one bar in the memory even if you initialize thousands of instants of Foo.


This depends on the language to language or the designer of the language. If I talk about Java, static members store in the Method area of the JVM and all the object are linked to them. One more thing that is very important to know is that we can access the static data member without creating the object of the class.It means the allocation of the memory to the static data members doesn't depend on the creation of the object of that class.


By specification static variables are stored in Constant Pool. JVM stores this info in Permanent Generation.


Typically Static variables are stored on the data-segment of the program memory. so for every class that is created/is in the running program will create the static variable on data-segment and all other variables are initialized in the code segment.

so basically it is like

+++++++++++++++++++++++++++++++++++++
+ DATA Segment
+   -static vars
+   
+----------------------------------
+  instances | instances | instances|
+            |           |          |

here single area is shared among instances.

from wikipedia "The data area contains global and static variables used by the program that are
explicitly initialized with a value."

ReferenceURL : https://stackoverflow.com/questions/14781993/how-exactly-do-static-fields-work-internally

반응형