gitdainn / DirectX11_Practice2D

c++ 공부 목적의 DirectX11 라이브러리를 이용한 2D 프로젝트입니다.
0 stars 0 forks source link

[디버깅] 메모리 누수 추적 방법 #11

Closed gitdainn closed 6 months ago

gitdainn commented 6 months ago

📝Description

CTexture::Create() 호출 시 메모리 누수 발생, 미호출 시 누수가 발생하지 않는 현상. 외부 Tick 함수나 다른 Create 또는 Add_Prototype() 함수와 관계 없이 CTexture의 존재 유무에 따라 여러 메모리 누수가 발생. CTexture는 생성 외에는 전혀 호출되지 않고, m_Coponents에서 메모리 해제도 정상 확인했는데 다양한 메모리 누수를 불러오는 이유를 모르겠음. image

⛔Problem

메모리 누수 발생

🔧Try

  1. 코드 주석 걸며 디버깅하여 확인

    • 메모리 누수가 수없이 뜨거나 실행 시간만큼 증가한다면 먼저 Tick 호출 부분에 주석 걸어보기
    • 소멸자 부분 중단점 걸어서 제대로 해제되는지 체크해보기
  2. 데이터 디버깅 사용

    • 디버그 > 새 중단점 > 데이터 중단점에서 해당 주소의 데이터가 변경될 때 중단점을 걸 수 있음.
    • ex. m_pRenderer의 RefCnt가 기하급수적으로 늘어날 때 어느 시점에 증가하는지 알기 위해 데이터 중단점 가능
    • 그러나.. 본인은 디버깅 소스파일을 찾지 못해 사용하지 못함.
    • 성능 프로파일러 > 메모리 사용량으로 체크할 수도 있다고 함.
  3. 디버깅 추적 코드 사용 (해당 방법으로 비교적 수월하게 해결함) 디버깅 추적 코드 사용 시 메모리 해제가 되지 않은 D3D11 COM 객체의 RefCnt와 이름을 알 수 있음.

3-1. 디바이스 생성 부분에 디버깅 플래그 넣어서 생성 (메모리 누수를 표시함)

3-2. 디버깅 추적 함수 (메모리 누수를 추적하며 보다 자세하게 표시해줌)

pragma comment(lib, "dxguid.lib")

void list_remaining_d3d_objects() { HMODULE dxgidebugdll = GetModuleHandleW(L"dxgidebug.dll"); decltype(&DXGIGetDebugInterface) GetDebugInterface = reinterpret_cast<decltype(&DXGIGetDebugInterface)>(GetProcAddress(dxgidebugdll, "DXGIGetDebugInterface"));

IDXGIDebug* debug;

GetDebugInterface(IID_PPV_ARGS(&debug));

OutputDebugStringW(L"Starting Live Direct3D Object Dump:\r\n");
debug->ReportLiveObjects(DXGI_DEBUG_D3D11, DXGI_DEBUG_RLO_DETAIL);
OutputDebugStringW(L"Completed Live Direct3D Object Dump.\r\n");

debug->Release();

}

endif

`

3-3. D3D11 COM 객체 한정 이름을 지정해서 띄울 수도 있음. pResource->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("Device") - 1, "Resource"); image

✅Solution

오늘의 교훈.

  1. 외부 함수로부터 값을 받아올 때 동적 할당된 데이터를 반환할 수 있으니 해당 데이터도 메모리 해제 해주기.
  2. 엔진에서 값 수정 시 무조건 빌드 후 업데이트해야 수정된 코드로 적용되니 주의하기 image image

-> CTexture::Initialize에서 GetResource와 QueryInterface로 받아온 부분이 메모리 해제가 안되서 발생한 문제였음.

📚Reference

참고자료