D3D Memory Leaks & 'lAllocID' Values

Started by
3 comments, last by jollyjeffers 18 years, 10 months ago
Evening all, One of those classic moments where I've completely confused myself [sad] I know I've done this before (somehow) but I've forgotten. In testing out some memory leak checking stuff, I modified one of the DXSDK samples so it didn't release one of the ID3DXMesh objects. Consequently you get:
Direct3D9: (INFO) :MemFini!
Direct3D9: (ERROR) :Memory still allocated!  Alloc count = 149
Direct3D9: (ERROR) :Current Process (pid) = 00000e28
Direct3D9: (ERROR) :Memory Address: 00da4f94 lAllocID=1 dwSize=000047f8, ReturnAddr=00fc14db (pid=00000e28)
Direct3D9: (ERROR) :Memory Address: 00dab944 lAllocID=9 dwSize=00001290, ReturnAddr=00fb8044 (pid=00000e28)
Direct3D9: (ERROR) :Memory Address: 00dab84c lAllocID=10 dwSize=00000008, ReturnAddr=00fb8132 (pid=00000e28)
Direct3D9: (ERROR) :Memory Address: 00dacc0c lAllocID=11 dwSize=000003a0, ReturnAddr=00fb970f (pid=00000e28)
Direct3D9: (ERROR) :Memory Address: 00dab88c lAllocID=12 dwSize=00000044, ReturnAddr=00fc14db (pid=00000e28)
Direct3D9: (ERROR) :Memory Address: 00da97c4 lAllocID=13 dwSize=00000050, ReturnAddr=00fc14db (pid=00000e28)
Direct3D9: (ERROR) :Memory Address: 00da9ae4 lAllocID=22 dwSize=000006bc, ReturnAddr=00fd2f4b (pid=00000e28)
Direct3D9: (ERROR) :Memory Address: 00dacfe4 lAllocID=24 dwSize=000016c8, ReturnAddr=00fc4a19 (pid=00000e28)
Direct3D9: (ERROR) :Memory Address: 00dab904 lAllocID=26 dwSize=00000008, ReturnAddr=00fc4b5d (pid=00000e28)
Direct3D9: (ERROR) :Memory Address: 01290064 lAllocID=28 dwSize=00003508, ReturnAddr=00fc14db (pid=00000e28)
Direct3D9: (ERROR) :Memory Address: 00daa1d4 lAllocID=29 dwSize=00000198, ReturnAddr=00fc14db (pid=00000e28)
Direct3D9: (ERROR) :Total Memory Unfreed From Current Process = 45808 bytes
Now, I was pretty sure I remembered that the lAllocID field for each (ERROR) could be used to find the offending object. There are lots more (ERROR) entries than actual leaks because it's reporting the owners of the leaked object as well. So, I fire up the control panel: And plug in my 11 values for the "Break On AllocID" field. Run my application again, and they all point to either the Direct3DCreate() or CreateDevice() call. None of them go to the ID3DXMesh that is actually being leaked. Through a bit of random checking, the ID3DXMesh mesh is actually lAllocID=146; which breaks where expected (on a D3DXLoadMeshFromX() call). Now, what I was wondering - anyone here tell me which bit it is that I'm forgetting/missing? I'm ready and waiting to be pointed and laughed at for being stupid [smile] Cheers, Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Advertisement
Subordinate objects often AddRef their parent. e.g. IDirect3DDevice AddRef's IDirect3D - so failing to release the IDirect3DDevice would show two leaks - one in IDirect3D and one in IDirect3DDevice. IIRC the AllocId's are in order of creation, so the lower the Id, the earlier that interface was created.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Quote:Original post by S1CA
Subordinate objects often AddRef their parent. e.g. IDirect3DDevice AddRef's IDirect3D - so failing to release the IDirect3DDevice would show two leaks - one in IDirect3D and one in IDirect3DDevice. IIRC the AllocId's are in order of creation, so the lower the Id, the earlier that interface was created.

Cheers for the reply... this pretty much confirms what I thought it was doing [smile]

However, I'm sure I remember a way of using that debug spew to actually identify the particular object that wasn't free'd.

That is, I managed to get it to break-point/identify the line where my ID3DXMesh was created, rather than just break-point on the parent/owner. I suppose it was always possible that I was using some of my own debugging code for this though.

Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Actually, something else to bear in mind is that since the D3DX library is separate from the D3D runtime, its allocations won't show up in the AllocId's generated by the runtime.

If you're using a static library version of D3DX, the allocations it makes will be via "new", and so will show up as leaks in your code rather than leaks from the D3D runtime.

Am obvious complication with this is if a D3DX object AddRef's a D3D object - so without "traditional" leak tracking in your own app, you may also miss some D3DX leaks that have affected D3D objects.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Quote:Original post by S1CA
Actually, something else to bear in mind is that since the D3DX library is separate from the D3D runtime, its allocations won't show up in the AllocId's generated by the runtime.

aaaah, the penny drops - makes perfect sense [smile]

It's probably a safe assumption that ID3DXMesh is creating an IDirect3DVertexBuffer9 and a IDirect3DIndexBuffer9 object internally. These not being freed would show up, but I don't strictly have any knowledge that they exist...

I guess it was some of my own code that managed to highlight the correct line of code previously.

Thanks for the replies - appreciated!
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

This topic is closed to new replies.

Advertisement