Help, Texture.Dispose() results memory leaks

Started by
7 comments, last by Gorrotz 15 years, 11 months ago
Hello, I'm working with Managed Direct3D Mobile on a Dell Axim x51v. I have some problems with textures in the video memory and I hope some of you might know how to fix this. Why are do these lines of code produce memory leaks? int membefore = device.GetAvailablePoolMem(Pool.VideoMemory); //Load a Texture Texture texture = TextureLoader.FromFile(device, "someTexture.dds"); //Delete it immediatly texture.Dispose(); int memafter = device.GetAvailablePoolMem(Pool.VideoMemory); int memlost = membefore - memafter; If I repeat this few times the video memory is full and creating a new texture fails. Question now is: How to *really* dispose a texture? Btw, the texture I get there is working, but i need to change textures several times which is difficult when 16MB video memory quickly run to zero...
Advertisement
As i know, the resources releasing it's automatic managed by garbage collector. The Dispose() method should be used only for explicit resource delete.
No. Dispose() frees unmanaged resources. You should call it when you are finished with the resource -- it should (if properly implemented) be done for you in the finalizer, but that is nondeterministic. Thus, if you need deterministic release of those unmanaged resources, calling Dispose() is the way to go (generally we have the using() pattern for this).

MDX did some funny things with respect to object lifetime. I don't have MDX assemblies around any more on this machine to Reflector, though. Those calls are not necessarily the most accurate either.

EDIT: You can also consider using SlimDX, since MDX is basically dead. I glossed over the 'mobile' bit. Fairly sure SlimDX will not run on a mobile platform. Nevermind.

[Edited by - jpetrie on April 24, 2008 11:35:17 AM]
One thing worth noting here is that creating textures outside of the managed pool should be avoided in most cases. D3D will handle swapping managed textures in and out of video memory as needed.

If you need some textures in the default pool, say for render targets, then create those once on startup (and recreate them after you recover from a lost device).

That should minimize the chances of you from running out of video memory.
Hello,

ManagedPool is a great thing, but unfortunatly my device caps tell me:
SupportsManagedPool: False
SupportsSysTexture: False

Funny thing is: I can try to create it with Pool.Managed or Pool.SystemMemory, but it seems to be ignored

texture = TextureLoader.FromFile(device, "someTexture.dds", 0, 0, 0, Usage.Texture, Format.R5G6B5, Pool.SystemMemory, Filter.None, Filter.None, 0);

and after it's created SurfaceDescription.Pool says VideoMemory


I already tryed
texture.Dispose();
texture = null;
GC.Collect();
Thread.Sleep(1000);
And still the lack of memory.... :(
Are you using Debug dlls?
If there is a memory leak, it will signal it.
Is this on a Sony Ericsson K700?

If so it seems to be a known bug. See http://developer.sonyericsson.com/thread/25018

I guess you'll have to work round it by reusing the textures.
Interesting. I found the solution. It's all about the Pixelformat.

There is the dds file:
dummyAtlas512.dds 512x512, 10 Mipmaps, Format: R5G6B5 (683KB)


Case 1:

PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
Device device = new Device(0, DeviceType.Default, this, CreateFlags.None, presentParams);

int membefore = device.GetAvailablePoolMem(Pool.VideoMemory);

Texture texture = TextureLoader.FromFile(device, "dummy.dds");

texture.Dispose();

int memafter = device.GetAvailablePoolMem(Pool.VideoMemory);
int memlost = membefore - memafter;


When I look at the textures format before it is disposed, it says: R5G6B5 (correct)
Anyway, after disposing it, there is a memory leak of: 524.288 Bytes



Case 2:

PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
Device device = new Device(0, DeviceType.Default, this, CreateFlags.None, presentParams);

int membefore = device.GetAvailablePoolMem(Pool.VideoMemory);
Texture texture = TextureLoader.FromFile(device, "dummy.dds", 0, 0, 0, Usage.Texture, Format.Unknown, Pool.VideoMemory, Filter.None, Filter.None, Color.White.ToArgb());
texture.Dispose();

int memafter = device.GetAvailablePoolMem(Pool.VideoMemory);
int memlost = membefore - memafter;


When I explicit say to get all information from the file (which I think Case 1 should also do!), the texture format it says: A1R5G5B5
But after disposing there is no leak.
Just to complete this topic, perhaps somebody will find this useful if he googles it...

It is NOT the Format Flag which causes the lack.
If you do not specify a transparent Color and set it 0 like this:
Texture texture = TextureLoader.FromFile(device, "dummy.dds", 0, 0, 0, Usage.Texture, Format.Unknown, Pool.VideoMemory, Filter.None, Filter.None, 0);
it takes double amount of memory and the texture can't be disposed correct (at least on my device)

Set a color like Color.White.ToArgb() and everything will be fine.

This topic is closed to new replies.

Advertisement