Jump to content
  • Advertisement
Sign in to follow this  
janoside

MDX - Device.Dispose takes a LONG time

This topic is 4592 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

When shutting down my MDX application, calling Device.Dispose() is taking a very, very long time (32 seconds last run). Is there any reason for this? What should I do to speed it up? Any ideas will be helpful since I have no clue how to even begin solving this. Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
You have some resource (texture, cubemap, shader, etc) which you havent disposed of. You need to dispose of everything before your app ends, or the garbage manager will need to track down and dispose of every resource still in memory.

Share this post


Link to post
Share on other sites
Make sure you do:

"Device.IsUsingEventHandlers = false";

Basically, keep this static value at false until you need it.

Graphic Item Initialization Example:


Device.IsUsingEventHandlers = true;
CurrentDevice.DeviceLost += new EventHandler(OnInvalidate);
CurrentDevice.DeviceReset += new EventHandler(OnRestore);
CurrentDevice.Disposing += new EventHandler(OnDispose);
Device.IsUsingEventHandlers = false;



Why, you ask? Because otherwise it creates a huge chain of events that have to unwind every time you Dispose().

Share this post


Link to post
Share on other sites
I support Cadef's answer, check whether you have some resources that you haven't disposed of yet. Basically you should dispose of your device last.

Share this post


Link to post
Share on other sites
Read about this on Tom's blog. As other have alluded you are likely creating MDX objects which are automatically hooking into the MDX event handling. This means that even though you let them go out of scope and expect them to be tidied on the next GC they will not be GC'd until the end and if the creating happens in your render loop there is probably thousands of them. Its not sufficient to let most MDX object go out of scope you have to call dispose on them or use using {} properly.

The AutoEventHandler will stop the big delay at the end but it doesn't solve the fundamental problem that you are not disposing things properly. Since almost all the MDX objects wrap native resources they have to be disposed. Sure the GC will tidy everything up for you EVENTUALLY but disposable objects that are not disposed by you explicitly take 2 GC cycles to be tidied up (see below) and are always promoted to the next level of GC which is a bad thing.

(1st GC finds its not used but since there is a finalizer it adds it to the finalizer queue and promotes the object to GC1. The finalizer thread eventually calls the finalizer and disposes the object. Next time there is a GC1 the object will be removed from memory.)

Share this post


Link to post
Share on other sites
ZMan, one of the reasons why we see this shutdown problem over and over again is IMHO a big design flaw in the current MDX version.

Most people will have no problem to call Dispose for objects they have created with a “new” as this is common in the managed world. Calling Dispose for objects that are build with a static “Fromxyz” or “Createxyz” method are less common but still something C# and VB developers can understand.
The big problem are IMHO all the Get* methods that returns other DirectX objects like GetSurfaceLevel or GetBackBuffer. Most people don’t know and I don’t see it in the docs that you have to dispose these objects too. If you don’t do this every time you request such an object an additional one is added to the event chain of the parent object.

If you work without the default event handling and forget to dispose such objects it could be even worse because the managed objects will hold references to the unmanaged world. As long as they are not collected from the GC there is a high possibility that you are not able to reset the device.

I must confess that during the design of my managed Direct3D 10 layer I have done the same mistake first too. But then I changed the whole stuff to make sure that there will always only one instance of a managed object for every unmanaged one. With this and some other changes it was possible to make sure that the user need only call Dispose for instances that were created with new. Even if the Dispose is not called the GC will find the unused objects and removed them.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!