2012-03-06 3 views
1

내 코드에서이 호출에 메모리 누수를 추적했습니다메모리 누수가 ++/CLI는 방법

BitmapSource snapshot = VideoPlayer.GetCurrentImage(); 

위해 VideoPlayer는 C++/CLI 라이브러리 및이 방법에 대한 코드입니다 :

WriteableBitmap^ VideoPlayback::GetCurrentImage() 
{ 
    BITMAPINFOHEADER bih; 
    BYTE *pDib = 0; 
    DWORD cbDib = 0; 
    LONGLONG timeStamp = 0; 

    memset(&bih, 0, sizeof(bih)); 
    bih.biSize = sizeof(BITMAPINFOHEADER); 
    HRESULT hr = m_pPlayer->GetCurrentImage(&bih, &pDib, &cbDib, &timeStamp); 

    if (FAILED(hr)) throw gcnew MFException(hr); 

    WriteableBitmap^ res = ToWritableBitmap(bih, pDib, cbDib, true); 

    CoTaskMemFree(pDib); 

    return res; 
} 

및 ToWriteableBitmap : 일부 개체

WriteableBitmap^ VideoPlayback::ToWritableBitmap(const BITMAPINFOHEADER& bih, BYTE* pDib, DWORD cbDib, bool bInvert) 
{ 
    WriteableBitmap^ res; 
    AtlTrace(_T("image size: %d x %d, bitCount: %d, bufferSize: %d\n"), bih.biWidth, bih.biHeight, bih.biBitCount, cbDib); 

    switch (bih.biBitCount) 
    { 
     //could there be any other format!? 
    case 24: 
     //AtlTrace(_T("24bit image not supported!")); 
     res = gcnew WriteableBitmap(bih.biWidth, bih.biHeight, 72.0, 72.0, System::Windows::Media::PixelFormats::Bgr24, nullptr); 
     break; 
    case 32: 
     res = gcnew WriteableBitmap(bih.biWidth, bih.biHeight, 72.0, 72.0, System::Windows::Media::PixelFormats::Bgr32, nullptr); 
     break; 
    } 
    if (res!=nullptr) 
    { 
     int stride = res->BackBufferStride; 
     res->Lock(); 

     if (bInvert) 
     { 
      BYTE* pBuf = (BYTE*)res->BackBuffer.ToPointer(); 

      BYTE* pDest = pBuf + (bih.biHeight - 1) * stride; 
      BYTE* pSrc = pDib; 
      //the image is inverted 
      for (int y = 0; y < bih.biHeight; y++) 
      { 
       memcpy(pDest, pSrc, stride); 
       pSrc+=stride; 
       pDest-=stride; 
      } 
     } 
     else 
     { 
      BYTE* pDest = (BYTE*)res->BackBuffer.ToPointer(); 
      memcpy(pDest, pDib, bih.biSizeImage); 
     } 

     res->AddDirtyRect(System::Windows::Int32Rect(0, 0, bih.biWidth, bih.biHeight)); 
     res->Unlock(); 
    } 
    return res; 
} 

호출이 방법을 여러 번 결과 "고정"되고 높은 DeadThr 내가 windbg에서 !threads을 실행할 때의 ead 카운트. 이러한 죽은 스레드에 !gcroot 실행 내가 얻을 :

DOMAIN (00000000036553A0) : 핸들 (고정 된)을 : 5417c8 : 루트 : 0000000022423378 (은 System.Object []) ->
00000000125f0c08 (System.Collections.ArrayList) ->
0000000012d96950 (은 System.Object []) ->
0000000012e44460 (System.Windows.Media.MediaContext) ->
0000000012e43e80 (System.Windows.Threading.Dispatcher) ->
0000000012e30480 (하여 System.Threading. 스레드)

주소가 System.Object[] 인 경우 항상 같습니다.

스레드가 완료 될 수 있도록이 호출 후에 어떻게 올바르게 정리해야합니까? 아니면 C++ 코드에 문제가 있습니까?

+1

CLR은 고정 된 개체 배열을 사용하여 통계를 저장합니다. 나는 소스에서 정적 ArrayList를 찾는다. –

+1

더 많은 코드를 첨부해야한다고 생각합니다. 내 생각 엔'ToWritableBitmap' 함수가 될 것입니다. 데이터를 복사하지 않습니까? – Krizz

+0

당신은 많은 스레드를 얻었지만 게시 한 코드에는 스레딩이 있다고합니다. 어쩌면 살펴 봐야 할 부분일까요? – svick

답변

0

문제점은 백그라운드 스레드에서 BitmapSource를 작성하는 것이 었습니다. Dispatcher.Invoke를 사용하여이 메서드를 호출하면 스레드 누출이 사라졌습니다.

관련 문제