2012-01-03 2 views
11

나는 안전하지 않은 코드를 사용하여 WPF의 WriteableBitmap을 받아 BackBuffer에서 직접 읽는 방법을 사용합니다. 한편으로여기서 GC.KeepAlive가 필요합니까? 아니면 객체를 유지하면서 지역 및 인수에 의존 할 수 있습니까?

int MyMethod(WriteableBitmap bmp) 
{ 
    return DoUnsafeWork(bmp.BackBuffer); 
} 

MyMethod의 스택에 bmp에 대한 참조가 남아 :

내가 같은 것을 할 때마다 내가 GC.KeepAlive을 사용할지 여부를 완전히 명확하지 않다. 다른 한편으로 구현 세부 사항에 의존하는 것처럼 보입니다. 예를 들어 bmp에 대한 참조를 유지하지 않고도 DoUnsafeWork을 입력하면 꼬리 호출로 컴파일 할 수 있습니다. 이론적으로

int MyMethod() 
{ 
    WriteableBitmap bmp1 = getABitmap(); 
    var ptr = bmp.BackBuffer; 
    WriteableBitmap bmp2 = getABitmap(); 
    return DoUnsafeWork(ptr, bmp2); 
} 

bmp1에 대한 참조 메서드가 반환 될 때까지 스택에 남아 있지만 다시는 구현 상세를 사용하는 것 같아 :

마찬가지로, 다음의 가상 코드를 상상한다. 물론 컴파일러는 bmp1bmp2을 병합하는 것이 자유 롭습니다. 왜냐하면 컴파일러가 결코 그런 일을하지 않을지라도 JITter가 여전히 가능하고 아마도 그렇습니다 (예를 들어 둘 다 동일한 레지스터에 저장함으로써 하나, 다른 하나).

그래서 일반적으로 객체에 대한 유효한 참조 인 지역/인수에 의존해야합니까? 아니면 정확성을 보장하기 위해 항상 GC.KeepAlive을 사용해야합니까?

특히, 이것은 분명히 FxCop thinks GC.KeepAlive is always bad이므로 수수께끼입니다.

+2

관련 독서 : [? 나는'사용해야 할 때 GC.KeepAlive'] (http://blogs.msdn.com/b/oldnewthing/archive/2010/08/13/ 10049634.aspx) 및 [가비지 수집을 위해 개체를 사용할 수있는시기는 언제입니까?] (http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048149.aspx) Raymond Chen 블로그 –

+0

@DanielPryden 우수 링크; 나는 물었다 전에 첫 번째하지만 두 번째 아닌 봤어요. 이미 물어 보았던 것 이외에,'this'는 현재 객체를 유지하지 못한다고 설명합니다. –

답변

12

개체에 대한 유효한 참조 인 지역/인수에 의존해야합니까?

아니오. 지터는 가비지 컬렉터에게 관리 코드에 의해 더 이상 사용되지 않는 순간에 로컬의 내용이 죽었다는 것을 전적으로 그 권리 범위 내에두고 있습니다.

정확성을 보장하기 위해 항상 GC.KeepAlive를 사용해야합니까?

예. 그것이 바로 그 때문입니다.

0

백 버퍼를 가져 오기 전에 WriteableBitmap.Lock을 호출 한 경우 WriteableBitmap을 고정해야하며 기본 메모리가 이동되지 않습니다. 적어도 WriteableBitmapAPI에 대한 나의 해석입니다.

필자는 WriteableBitmap을 광범위하게 사용했으며, 특히 오픈 소스 WriteableBitmapEx 라이브러리 (codeplex) (공개,이 라이브러리에는 한 번만 기여했지만 프로젝트에는 포함되지 않았습니다)를 사용했습니다. 잠금/액세스 백 버퍼 (반복)/잠금 해제/무효화 패턴을 사용하여 그립니다. Backbuffer IntPtr이 구조체에 저장되어 있고 응용 프로그램을 전달한 경우에도이 패턴에 문제가 없었습니다.

안부,

+0

나는 Lock/Unlock이 나타날 것이라는 것을 알고 있었고, 나는 읽는 동안 그것을 잠그지 않는 것이 좋지 않을 수도있다. (문서는 글을 쓰는 동안 왜 잠 가야 하는지를 설명한다.) 그러나 이것은 포인터를 수정하는 것과는 아무런 관련이 없습니다. 'BackBuffer'는 MSDN에 따라 고정 될 것이 보장됩니다. –

+0

흠, 그걸 알지 못했습니다, 고마워요! 잠금/잠금 해제는 값 비싼 작업이기 때문에 자습서에서 몇 가지 테스트를 수행합니다. 질문에 대해서는 GC가 여전히 범위 내에 있지만 더 이상 사용되지 않는 항목을 수집하는 것과 같은 이상한 일을합니다 . 코드 예제로 Release 나 Debug에서 다른 결과를 얻나요? –

+0

질문은 이론적이다; 나는이 유형의 코드로 어떤 실제적인 잘못을 아직 보지 못했다. 사실 현재 컴파일러/JIT에서 항상 작동하는 경우 놀라지 않을 것입니다. –