When I close my application, I get the following errors in the Direct3D Debug output:

Direct3D9: (INFO) :MemFini!
Direct3D9: (ERROR) :Memory still allocated!  Alloc count = 20
Direct3D9: (ERROR) :Current Process (pid) = 0000162c
Direct3D9: (ERROR) :Memory Address: 05fb7d0c lAllocID=50 dwSize=000170d8, ReturnAddr=0615e508 (pid=0000162c)
Direct3D9: (ERROR) :Memory Address: 08c86594 lAllocID=1046 dwSize=00004bc4, ReturnAddr=0614d5ea (pid=0000162c)
Direct3D9: (ERROR) :Memory Address: 08d0c31c lAllocID=1471 dwSize=00001a40, ReturnAddr=0615e784 (pid=0000162c)
Direct3D9: (ERROR) :Total Memory Unfreed From Current Process = 258932 bytes

I've carefully looked over my code and the one thing I found suspect was a texture and a surface I got from the texture. I realised that surface->Release() wasn't returning 0, which means, I believe, that someone else still has a reference to it. So just to try something, I released it several times in a while loop until it returned 0. Direct3D then returned the following error:

Direct3D9: (ERROR) :A level of a mip-map has been released more often than it has been add-ref'ed! Danger!!

I don't get it. That surface is somehow referenced more than once but hasn't been "add-refed" more than once? How can I debug who is holding a reference to it?



In my experience, the most likely causes of resource leaks are:

  • Failing to call OnLostDevice for any D3DX objects you use (and that implement OnLostDevice) - Effect and Sprite are common criminals here as they will AddRef a texture that they use (to ensure that the texture isn't destroyed while they may still be using it); I believe that this shouldn't be necessary during shutdown, however, but if it sounds like something you may have then it's no harm doing it.
  • Failing to call Release for each call to GetSurfaceLevel you make. GetSurfaceLevel will increment the reference count on the returned surface, so not Releasing it will cause the leak.
  • Failing to call Release for each call to GetRenderTarget or GetBackBuffer you make; likewise increments the reference count on the returned surface (as a general rule, any D3D Get* call that returns an interface must have a Release call on the returned interface, otherwise it will leak.)

The last two seem probable in your case, so your first step in debugging is to make sure that your code respects this rule; a quick find-in-files for "->Get" should help you easily identify anything of this nature you may have.

Once you've checked this out, and if you're still leaking, post back and we'll see what the next steps are.

  • \$\begingroup\$ I proceeded by progressive commenting-out of everything direct3d-related, and eventually I found the culprit. It was a "Get" method as you pointed out; I had replaced passing a IDirect3D9* pointer with getting it from the device with GetDirect3D, not realizing that this method increments the reference count. \$\endgroup\$
    – Asik
    Feb 19 '13 at 15:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.