Jen*_*rer 5 c++ memory directx direct3d
我遇到了我的Direct3D应用程序中的泄漏,我最终纠正了它,但我认为泄漏的原因是由于我对Direct3D如何处理其内存和接口的误解.
我无法找到关于它的权威文章/教程(请提供一个,如果你有一个),但从我收集的,它的工作原理如下:
Get
方法时,返回的对象的引用数量都会增加.因此,如果我调用GetRenderTarget
,渲染的表面的引用计数会递增.Release
接口会减少其引用计数.前两个点的组合基本上意味着:每次获得界面时,请在完成后释放它.我不完全确定这是否正确,但似乎在实践中有效.如果有人能澄清/确认它是如何运作的,那就太好了.
PS,在发布接口时是否有任何保护措施?Release
在后台缓冲区上调用任意次数似乎没有造成任何损害(这是一件好事,但我不确定为什么不这样做).
Direct3D基于COM,这是一项至少15年的技术.似乎很多人声称COM已经死了,因此许多人忽略了它,但现实是Windows中有许多东西,包括Direct3D和MS的新媒体基金会都是基于COM的.
我强烈建议你看看一般的COM编程.有大量的书籍和资源,但其中很多都相当陈旧但是没关系,因为技术的根源在很长一段时间内都没有改变.
基本上你所观察到的是接口引用计数.COM完全基于通过接口访问对象,这些接口都来自基本接口IUnknown.IUnknown实现方法AddRef()和Release(),只要存储指针的本地副本并且每当不再需要本地副本时调用Release(),应用程序就有责任调用AddRef().
如果你有带接口输出参数的方法(即IFoo**ppObj),这意味着被调用者给你一个接口,现在你拥有它,你完成它时仍然有责任调用Release().
一旦掌握了它,我建议你开始使用CComPtr智能类来存储本地和成员变量(仍然在函数调用之间传递原始接口值,不需要智能指针参数类型).它会照顾你所有的引用计数.也不要将其称为"任意数量"的释放.今天它可能会起作用,因为对象是作为单例实现的,或者可能还有其他东西,但是这可能会随着下一个补丁或下一个版本而改变.始终遵守规则.如果你有一个接口,当你不需要它时,只需调用Release()一次.如果你制作了一个接口指针的副本,请确保只调用一次AddRef().