2012-09-28 1 views
1

그래서이 질문은 C#에서 참조 개체의 실제 주소를 가져 오는 것에 대해 몇 번 본적이 있습니다. 일반적인 합의는 이것이 가능하지 않은 것으로 보입니다 GCHandle.AllocGCHandleType.Pinned으로 호출 할 수 없기 때문에 고정 된 개체의 주소를 가져올 수 있습니다.참조 개체의 주소가 직접 실행 창에서 작동하지만 컴파일 된 코드가 아님

내가 이상한 것을 알았지 만 Visual Studio 디버거에서 개체를 로컬 창에서 메모리 디버그 창으로 끌어서 참조 개체의 주소와 메모리를 볼 수 있습니다. 즉각적인 창 &obj을 입력하고 객체의 실제 주소를 가져올 수도 있습니다 (이 주소는 메모리 창에 표시된 것과 정확하게 일치합니다).

그러나 왜 내 컴파일 된 코드에서 같은 전화 ... 예를 할 수없는 것이 있습니다 : 직접 \ 메모리 창 관리 유형, 심지어 디스플레이의 주소를 얻기 위해 허용되는 방법

object someObject = new Object(); 
&obj; // Compiler Error: Cannot take the address of, get the size of, or declare a pointer to a managed type ('object') 

메모리의 레이아웃하지만 C#이 중 하나를 할 수 없어? C#에서 참조 객체의 실제 주소를 얻는 방법이 있습니까?

답변

2

디버거는 자신의 코드보다 큰 이점이 있습니다. 고정 된 상태에서 프로세스 상태를 볼 수 있습니다 아니요 코드가 실행 중입니다. 따라서 객체의 주소를 얻는 것은 문제가되지 않으며, 가비지 컬렉터는이를 무효화하기 위해 실행되지 않습니다.

+0

그러나 직접 실행 창에서 잘못된 C# 코드를 실행하는 것이 어떻게 가능합니까? –

+0

직접 실행 창에는 C# 컴파일러가 내장되어 있지 않습니다. 단순히 표현식을 평가합니다. & 연산자에는 문제가 없습니다. –

0

가비지 수집기가 개체 수명을 처리합니다. 또한 gen0, gen1, gen2 (Generations)라는 3 개의 '조각'으로 나뉩니다.

gen0에는 할당 된 메모리가 작은 빠른 살아있는 객체가 있습니다. 거기에 많은 단명 개체가 있기 때문에 가비지 수집은 자주 실행됩니다. 객체가 gen0을 유지하면 다음 세대로 이동합니다.

개체가 garbaged 수집 될 때 다른 모든 개체는 사용 가능한 메모리 공간을 유지하기 위해 메모리에 다시 배열됩니다.

하지만 gen2에서 가장 크고 수명이 긴 객체가있는 gen2에서는 gen2에서 객체를 이동하는 데 너무 많은 비용이 들기 때문에 메모리를 재 배열하지 않는 경우가 거의 없습니다.

이 메모리 참조 및 가비지 수집은 모두 C#과 같은 관리 환경에서 '무료'로 제공됩니다.

"string interning"과 같은 최적화가 수행되는 경우가 있습니다.

+0

죄송합니다. 그러나 이것이 어떻게 문제를 해결하는지 알 수 없습니다. –

+0

내가 말하고자하는 바 : GC가 객체를 재 배열했기 때문에 메모리 참조 'Now'가 'future'에서 올바르지 않을 수 있습니다. – Johnny

+1

@BrianRasmussen : GC 실행시 개체가 힙 내에서 이동할 수 있으므로 실제 주소가 변경됩니다! 따라서 관리 대상의 실제 주소를 가져올 수없는 이유가 설명됩니다. 즉각적인 창에서는 실제 상태의 스냅 샷 만 표시하므로 문제가되지 않습니다. –

관련 문제