I've been banging my head against the wall for the last few days trying to track down the source of a rather big memory leak in my Direct3D-application. Turns out the culprit seems to be the DrawText function. Let me explain exactly what happens:
I'm using a variable width truetype font (Times New Roman) created through D3DXCreateFont. I'm using this in various parts of my application, but the part where the problems are easiest to notice is in my custom UI textboxes. I use a function called InsertText to add new characters to the printed string, and everything I initialize is cleaned up properly afterwards.
The problems only truly begin upon typing the "f" or the "j" character, and only if they are lowercase. I assume it has something to do with them overlapping other characters. Every time a new character is added to the string after an f or a j has already been added, the application's memory footprint increases by a minimum of 300k, and in some cases can expand by over a MB. When the application exits, all of this memory is freed properly, leaving no leaks. As you can probably imagine, even just entering a line of chat in a chatbox could drain the computer of about 50 megs of RAM which won't be freed until the application exits.
I've tested this on three different computers. Two are nearly identical, and the problem appears on both. The third computer is older, but doesn't suffer from this issue.
Is this a known issue, or did I do something wrong What can I do to fix it, apart from using fixed-width fonts (which don't suffer from this) I'd *really* appreciate any help I can get with this.

Dramatic memory leak in DrawText
AlexV
Minh..... thats the best repro case I've ever seen. Testers around the world must love you.
This is just my redemption for years of actually WRITING bugs. :)
I'm working my way through the CustomUI sample right now, but my money is on the Sprite class having trouble with really skinny sprites.
folsomfisher
Having downloaded the April SDK, I can confirm that this bug has not been fixed. There is still major memory usage when DrawText has to deal with certain characters (depending on the font). Most importantly, this memory does not get freed up when the text is deleted! As a game developer creating a commercial game with chat functionality, this is unacceptable to me, and I'm now at a loss at how to proceed.
Should I wait and see if a fix for DrawText is released, or should I find a third-party text rendering function to use instead, costing me extra development time
Has anyone found a workaround to this problem
GJGrosso
The problem isn't really that it consumes obscene amounts of memory. The problem is that the memory doesn't seem to be released until the application closes, even if you delete all the text you wrote or even release the objects holding the text.
jlfappx
I wouldn't call the 300K to 1Mb memory usage that you reported as being "major".
What text The D3DX library doesn't create any "text" objects that you can delete. Do you mean the ID3DXFont object
southwynd
Jezzrel
I ran the executable straight off the DirectX Sample Browser (December 2005).
I also made a little movie of the demo. First I typed some good characters, then some j's which in a few seconds double the memory usage. I'm using the Task Manager for the measurement.
Here's the link to the movie.
http://MiddaySoftware.com/MinhsBlogs/Media/CustomUI_leak.wmv
Riiii
Turns out that this is "By Design". The reason this happens is that certain characters and certain languages (eg. Arabic) need to be rendered a word at a time, and not a glyph at a time. So when you try to render a long word made up of just 'j's, the font system needs to allocate one really big texture to hold all that information. That's why you're seeing memory usage rise.
If you want to, you can try inserting a few spaces, and you'll see that the memory usage won't spike as much.
Hope that helps. Thanks for the bug report, it's a very interesting side effect of the font render algorithm.
AlbertoSpin
George Henne
Ed Staffin
Thank you! Seriously, that workaround is a lifesaver. I won't be able to test it until after Easter, but it sounds like it would work.
As for the problem not being "major", a user could (on the systems we develop our game on) lose more than 100 MB by randomly hitting keys for a few seconds. With a way to clean the cache, this is no longer as major an issue for us as it used to be.
I guess the problem is solved for now. :)
VincentCroft
Essentially it comes down to this:
- D3DX needs to render words at a time to render fonts correctly. Rendering entire words at a time = lots of memory used up for long words. If you have a 200 character word, you will use a lot of memory. In practice though, this is not a frequently encountered case.
- D3DX needs to cache these words to maintain frame-to-frame coherency. If one word is being rendered this frame, the odds are pretty high that it will also be rendered next frame. D3DX maintains a cache to speed this up.
I don't think there's anything wrong with these two points, we're not going to change those. You can't expect D3DX to speculatively guess when certain cache tiles need to go away based on the statistical improbability of running into a given word in the future.
If you want to, you can recreate the font object between level loads to clear the cache. This is functionally equivalent to a proposed ClearCache method on the font object. That's the workaround.
rba18089
This problem seems to be very font related. For the two main textboxes in the CustomUI sample, the upper one only seems to generate the problem with the "j" character, while the bottom one also triggers when using "t". My own application, which uses Times New Roman (MS tends to use Tahoma), triggers upon "j" and "f".
It's looking more and more like a genuine DirectX bug.
Rob Chandler
What are the exact repro steps for CustomUI and where are you looking at memory
I updated CustomUI to use Times New Roman (the caret is now totally wrong!) and I'm looking in Task manager and in perfmon and I don't see any memory issues there.
Alastair Todd
Minh..... thats the best repro case I've ever seen. Testers around the world must love you.
Seems very odd.
Repro: if I run the EXE from C++ or Managed samples. If I run the VS2005 for the C++ sample (sorry can't try VS12003 don't have C++ installed for 03)
No Repro: if I run the VS2005/VS2003 solution for managed code using debug or release (which is why I missed the repro)
Interesting note I went through the alphabet and 'j' and 't' cause the issue for me
MS guys, seems like a pretty straightforward repro to me....