Resources are not being disposed when loading from a Windows Form

Started by
1 comment, last by Hyper Sonic 16 years, 11 months ago
Hi all. I'm having a problem I didn't notice until I tried my app in a box with ATI Rage XL video card with 8 MB in video memory. As much as I have read, most DirectX examples on the net call their DirectX form from the Main() function, so when the app ends, all resources are disposed because the program is completely destroyed. My DirectX app needs some configuration before being loaded, so I prompt the user to input game settings thru a Windows Form. When everything is ok, the user clicks on a Start button to begin my DirectX app. The code for this button is as follows:

try{
	using(MyGame game=new MyGame(GameSettings) ){
		try{
			game.Show();
			game.Run();
		}catch(Exception ex){
			MessageBox.Show("Error when running:\n- "+ex);
		}
	}
}catch(Exception ex){
	MessageBox.Show("Error when loading:\n- "+ex);
}

GC.Collect();


My original program uses a big RenderTarget (600x600) with a R5G6B5 Format and I know that this ATI card can only create this texture once. Trying to do it twice throws an OutOfVideoMemory exception. I dispose this texture at my DirectX form's Dispose method and I get back to my trigger form so everything is ok till this step. The problem comes when trying to begin my DirectX app again by clicking the Start button, I get an OutOfVideoMemoryException but Everything was supposed to be already disposed so I can't understand what is going on. I think this problem doesn't occur with my development machine because I have a much better card with 256 MB in video memory. I did a simple test with my machine. Instead of loading my DirectX app I created a simple DirectX app which only loads 14 low sized Pool.Managed textures. I'm already sure this simple app is disposing all textures. I watched Windows Task Manager Memory Usage column thru a coupe of runs. The results were the following: While Loader Windows Form is active and before doing first DirectX run: 17.9 MB During DirectX first run (a simple device + 14 small Managed textures): 35.048 MB After quitting DirectX first run (back to loader Windows Form): 31.416 MB (Shouldn't be 17.9 or closer??) During DirectX second run (the same app as first run): 35.508 MB After quitting DirectX second run (back to loader Windows Form): 34.504 MB During DirectX third run: 35.556 MB After quitting DirectX third run (back to loader Windows Form): 34.632 MB During DirectX fourth run: 35.604 MB After quitting DirectX fourth run (Back to loader Windows Form): 34.828 MB I really don't understand why the first DirectX run goes to 35 MB in memory and disposes only about 4 MB. Subsequent runs are more stable but memory usage is still going up after each run and this looks like a problem when using this application with old hardware. I think resources are not disposing properly, maybe my device or something else? The only solution I can figure out is to keep my DirectX app on a different Exe file and call it from my Windows Form so resources are released when the Exe file ends, but this requires me to Serialize/save/share my game settings thru both Exes and I think this is my last resource solution but I really want to find the appropriate solution. Any help will be greatly appreciated. Best Regards. [EDIT] I just did a new test, this time it's a simple DirectxX windows with no textures, only an initialized device. During first run memory is: 27.728 MB After first run: 27.664 MB Each subsequent run increases memory at almost the same rate. [Edited by - Hyper Sonic on May 10, 2007 3:44:31 PM]
Advertisement
In order to dispose of MDX objects you must call their Dispose method in a timely fasion, either by using a using style syntax (which I see you use on your game object) or by calling their dispose method in the containing object's dispose method.

You cannot call dispose from a finalizer (the things that look like C++ destructors), since they are not executed immediately, and often take a while to run.

Failing to call dispose on anything created will result in that memory being leaked until the application closes.

Assuming you've done all this and still get issues, there is a known issue with the MDX event handlers not allowing DirectX to properly release resources. To fix this, you'll need to disable MDX event handling completely, by setting:
Microsoft.DirectX.Direct3D.Device.UsingEventHandling = false;
(or something very similar).
This will disable all MDX events (device lost, resource created, etc.) but should aid in the case where resources are not getting released properly.

[EDIT] One final thing, you can use PIX to determine which objects are not being released by checking which resources are marked as "Alive" by PIX once the app closes. This can be very useful in finding why stuff isn't getting released.

Also, don't forget to call dispose on, or wrap in a using clause any Get MDX method that returns a disposable. Those need to be disposed of just like regular resources (especially confusing is Device.DepthStencilSurface, which also needs to be disposed of).

Hope this helps.
Sirob Yes.» - status: Work-O-Rama.
Hi sirob, I did as you said but things are the same.

BTW, I just edited my post before you could see it. And now I just realized that my DirectX form is using DirectSound and another component. I call this.Dispose() to release resources and my Dispose routine is as follows:

protected override void Dispose(bool disposing) {	if(disposing) {		if(myComponent!=null)myComponent.Dispose();		myComponent=null;		if(AudioDevice!=null)AudioDevice.Dispose();		AudioDevice=null;		this.EndGraphics();		if(components!=null)components.Dispose();		components=null;	}	base.Dispose(disposing);}protected void EndGraphics(){	//Dispose any textures ...	if(myDevice!=null)myDevice.Dispose();	myDevice=null;}


Just to make sure DirectSound or my component (which does not deal with DirectX) were not doing something strange, I disabled their initialization lines. I could see that without them, my DirectX form (only a device with no textures or anything strange) went from 17 to 20 MB. But ending this form still keeps memory at 20 MB instead of returning to 17. With DirectSound and my other component memory went from 17 to 27 MB and kept that way for any subsequent runs, so nothing is being disposed!!! The difference is that when using 14 textures, memory goes to 35 MB at first run.

Anyway, A simple DirectX application with an initialized device increases 3 MB in memory and keeps the same. It's not as bad as at the beginning but it still makes no sense to me that 3 MB of memory are kept after my DirectX form is disposed.

I'm specially worried about Video Memory because my rendertargets can crash my app when being created because those textures (or my device) are using memory even when they were manually disposed and that would be a problem with old hardware.

Regards

This topic is closed to new replies.

Advertisement