정적 필드는 내부적으로 정확히 어떻게 작동합니까?
수업이 있다고 하면,
class Foo
{
public static bar;
}
다음과 같은 경우:
new Foo();
저는 기억 속에, 이 물체를 위한 공간이 예약되어 있다는 것을 상상할 수 있습니다.
...그리고 당신이 다시 말할 때:
new Foo();
...이제 개체에 사용할 수 있는 다른 공간이 있습니다.
하지만, 정적 필드는 정확히 어디에 살고 있습니까?
제가 정말로 배우려고 하는 것은 다음과 같습니다.
개체에 대한 참조는 참조하는 개체의 동일한 필드를 어떻게 참조합니까?
유형 시스템의 정확한 세부 사항은 구현에 따라 다르지만, 단순히 종속적이며 신경 쓰지 말아야 한다고 말하는 것 이상으로 좀 더 자세히 설명하겠습니다.Microsoft의 구현(.)에서 대략적으로 작동하는 방법에 대해 설명하겠습니다.NET)은 제프리 리히터의 CLR via C# 책과 Hanu Kommalapati 등의 CLR이 런타임 객체를 생성하는 방법을 참조하십시오(원작 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);
인스턴스(instance) 필드는 어디에 있습니까?
당신이 말할 때마다new Foo()
개체 인스턴스에 대해 공간이 할당되고 초기화되며 생성자가 호출됩니다.이 인스턴스는 아래 이미지에서 Foo의 인스턴스로 표시됩니다.예: 클래스의 인스턴스 필드만 포함합니다(이 경우).myBar
그리고.myNum
되는 두 의 추가 ()가 사용됩니다.Sync block index
그리고.Type handle
은 . . . . . . . . . . . . . .Type
인스턴스 유형(이 경우 Foo 유형)을 설명하는 개체입니다.
라고 말할 때new Foo()
다시, 형식의 인스턴스 필드에 대한 공간을 다시 포함하는 새 공간이 할당됩니다.인스턴스 필드는 개체 인스턴스와 연결되어 있습니다.
런타임은 각 인스턴스 필드를 개체 데이터의 시작 부분에서 고정 오프셋으로 배치합니다.를 들면, 들면를예,myBar
오프셋 +4에 살 수 있습니다.인스턴스(instance) 필드의 주소는 단순히 객체의 주소와 필드의 오프셋입니다.
정적 필드는 어디에 있습니까?
C# 및 Java의 정적 필드는 개체 인스턴스와 연결되지 않고 유형과 연결됩니다.클래스, 구조체 및 열거형이 유형의 예입니다.정적 필드의 값을 유지하기 위해 할당된 일부 공간은 유형당 한 번뿐입니다.의정 필공할 것타니다합의 하는 것이 입니다.Type
, 형을설구하나로므이조도는하명유▁▁one▁that,▁only도 있기 때문입니다.Type
개체 유형별로 지정합니다.이것은 C#과 Java가 취하는 접근 방식입니다.
그Type
런타임에 의해 형식이 로드될 때 객체가 생성됩니다1.이 구조에는 런타임이 새로운 인스턴스를 할당하고 메서드를 호출하고 캐스팅을 수행하는 데 필요한 모든 종류의 정보가 포함되어 있습니다.또한 정적 필드에 대한 공간을 포함합니다. 이 경우bar
그리고.num
.
런타임이 각 정적 필드를 형식 데이터의 시작 부분에서 오프셋으로 지정했습니다.이것은 각 유형에 따라 다릅니다.를 들면, 들면를예,bar
오프셋 +64에 살 수 있습니다.는 정적필드의주다주다니입소의 입니다.Type
객체에 필드의 오프셋을 더한 값입니다.형식은 정적으로 알려져 있습니다.
Microsoft의 경우1.NET 여러 개의 서로 다른 구조는 MethodTable 및 EEClass 구조와 같은 유형을 설명합니다.
이는 해당 구현에 따라 완전히 달라집니다.C# 및 Java의 경우 런타임에서 변수에 대한 메모리를 저장할 위치를 결정할 수 있습니다.C와 대부분의 컴파일된 언어의 경우 컴파일러가 이 결정을 내립니다.
그렇긴 하지만, 실제로, 그것은 중요하지 않습니다.사양에 따라 결정된 사용량이므로 동작이 보장된다는 것을 알고 변수를 자유롭게 사용할 수 있습니다.
Java의 경우 정적 필드에 의해 참조되는 개체는 다른 개체와 마찬가지로 힙에 위치합니다.
힙은 모든 클래스 인스턴스 및 어레이의 메모리가 할당되는 런타임 데이터 영역입니다.
클래스가 로드될 때 필드가 초기화됩니다(선언에 초기화가 포함된 경우). 이는 다음 중 하나가 처음 발생하기 직전에 발생합니다.
- 클래스의 인스턴스가 생성됩니다.
- 클래스에서 선언한 정적 메서드가 호출됩니다.
- 클래스에서 선언한 정적 필드가 할당됩니다.
- 클래스에 의해 선언된 정적 필드가 사용되며 필드는 상수 변수가 아닙니다(§4.12.4).
정적 필드에 대한 액세스는 정적 및 정적 두 가지 특수 JVM 지침을 통해 수행됩니다.그러나 이러한 차이를 제외하고 정적 필드는 비정적 필드와 유사합니다.
이는 언어마다 크게 다르며 플랫폼마다 크게 다를 수도 있습니다.
예를 들어 에 있습니다.측에서 인 NET 측, 정적연구지됩조 "결니"와 ".EEClass
정의: 힙 할당 또는 "어디서나" 할당된 멤버일 수 있습니다(C# 규격은 힙/스택 동작을 지정하지 않으며 VM의 구현 세부 정보입니다).
저는 C#에 대해서만 잘 알고 있으며, 이것이 제가 이해하는 C#입니다.
그런 다음 프로그램이 시작되고 모든 관련 어셈블리가 AppDomain에 로드됩니다.어셈블리가 로드되면 정적 필드를 포함한 모든 정적 생성자가 호출됩니다.그들은 그곳에서 살 것이고, 그들을 언로드하는 유일한 방법은 앱도메인을 언로드하는 것입니다.
예외가 있을 수 있지만 참조 유형의 경우new
-dll은 일반적으로 "module"이라고 하는 내부 데이터 구조에 객체를 만듭니다.힙은 CLR(공통 언어 런타임)에 의해 관리됩니다.정적 또는 인스턴스 구성원이 있든 로컬 변수가 있든 상관 없습니다.
멤버의 가 없는 )static
즉, 정적 멤버는 유형(클래스, 구조체)당 한 번만 존재하고 인스턴스 멤버는 개체당 한 번만 존재합니다.
정적인지 아닌지는 참조일 뿐입니다. 이 구분은 참조된 개체에 적용되지 않습니다(개체가 값 유형이 아닌 경우).정적 멤버, 인스턴스 멤버 및 로컬 변수는 모두 동일한 개체를 참조할 수 있습니다.
정적 멤버 및 상수는 힙에 저장됩니다.가비지 수집을 가져올 수 있는 힙의 개체와 달리 정적 멤버 및 상수는 Appdomain이 해체될 때까지 유지되므로 정적 필드를 처리할 때 주의해야 합니다.
의 변수만 합니다.bar
Foo
.
이는 언어에 대한 언어 또는 언어 설계자에 따라 달라집니다.Java에 대해 이야기하면 정적 멤버는 JVM의 Method 영역에 저장되고 모든 개체가 이들에 연결됩니다.한 가지 더 알아야 할 것은 우리가 클래스의 객체를 만들지 않고도 정적 데이터 멤버에 액세스할 수 있다는 것입니다.이는 정적 데이터 멤버에 대한 메모리 할당이 해당 클래스의 개체 생성에 따라 달라지지 않음을 의미합니다.
규격별로 정적 변수는 상수 풀에 저장됩니다.JVM은 이 정보를 영구 생성에 저장합니다.
일반적으로 정적 변수는 프로그램 메모리의 데이터 세그먼트에 저장됩니다. 따라서 실행 중인 프로그램에서 생성되거나 실행 중인 모든 클래스에 대해 정적 변수가 데이터 세그먼트에 생성되고 다른 모든 변수는 코드 세그먼트에서 초기화됩니다.
그래서 기본적으로 그것은 같습니다.
+++++++++++++++++++++++++++++++++++++
+ DATA Segment
+ -static vars
+
+----------------------------------
+ instances | instances | instances|
+ | | |
여기서 단일 영역은 인스턴스 간에 공유됩니다.
위키피디아에서 "데이터 영역은 프로그램에 의해 사용되는 전역 및 정적 변수를 포함합니다.
값을 사용하여 명시적으로 초기화됩니다.
언급URL : https://stackoverflow.com/questions/14781993/how-exactly-do-static-fields-work-internally
'sourcecode' 카테고리의 다른 글
Python 요청 모듈로 PDF 파일 다운로드 및 저장 (0) | 2023.07.27 |
---|---|
UIPickerView가 로드된 후 행 선택 (0) | 2023.07.27 |
NumPy 배열에 숫자가 아닌 값이 하나 이상 포함되어 있는지 탐지하시겠습니까? (0) | 2023.07.27 |
jQuery 또는 CSS 선택기를 사용하여 일부 문자열로 시작하는 모든 ID 선택 (0) | 2023.07.27 |
내 코드가 Windows로 컴파일되고 있는지 확인할 수 있는 매크로가 있습니까? (0) | 2023.07.27 |