我一直在使用d3d11很長一段時間了,在發現directx調試器之後,我最近發現我的程序從所有沒有正確釋放的com對象的任何地方都漏出內存。經過幾個小時的盯着代碼窺探之後,我已經開發了一些方法來隔離哪些地方我得到了這些意外增加到ref計數。D3D11從哪裏增加裁判計數?
首先,所有的對象都被包裝在std :: shared_ptrs中,用定製的刪除器來調用它們各自的釋放函數。我這樣做是爲了不必調用addref,只有當對象超出範圍時纔會調用釋放的第一個調用,即刪除者中的調用。這將是這個樣子:
// in D3D11Renderer.h
...
// declaration
std::shared_ptr<ID3D11Device *> m_Device;
...
// after call to ID3D11CreateDeviceAndSwapChain
m_Device.reset(device, [](ID3D11Device * ptr){ptr->Release();})
問題是在API調用某些隨機函數將只是隨機增加引用計數,希望我以後有對付它。
東西,我發現,在診斷有用的是,看起來像這樣的功能:
template <typename T>
int getRefCount(T object)
{
object->AddRef();
return object->Release();
}
其中,只是增加和計數,以獲得該對象上裁判的當前計數遞減。使用這個,我發現,在調用定製刪除器的發佈之前,有10個未完成的對我創建的ID3D11Device的引用。好奇的是,我慢慢地回溯,在整個程序中調用這個函數,直到我最初創建它的地方。有趣的是,在我第一次創建對象之後(甚至在shared_ptr擁有所有權之前),優秀參考數已經是3!這發生在這之後立即發生。
result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1,
D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, NULL, &deviceContext);
if(FAILED(result))
{
return false;
}
這是我第一次調用創建設備的任何這樣的功能,當我檢查,看看有多少裁判之後也有,並說3!很明顯,我誤解了這些com對象應該被處理的方式。有沒有這樣的方式,我可以手動刪除它們,而不是使用那裏的幕後裁判廢話?
如果你手動刪除他們,而別的東西了他們一個參考,你的程序會崩潰。引用計數較高,因爲您已創建了保存對原始結構的引用的新結構。這很好,但是當新的結構被銷燬時,你可以釋放你的引用而不用擔心它,然後舊的結構會放棄它們的引用計數。 –