digitalmars.D - Odd behavior found in GC when terminating application
- solidstate1991 (13/13) Jan 05 2018 I usually write my applications' main logic into one or more
- Adam D. Ruppe (10/13) Jan 05 2018 The problem with this is when the GC runs, it considers
- Jonathan M Davis (4/17) Jan 05 2018 Either that or use structs on the stack instead of classes on the heap s...
- 12345swordy (3/10) Jan 05 2018 There been discussions regarding spiting up the destruction and
- H. S. Teoh (13/22) Jan 05 2018 Yeah, the GC does not guarantee any particular order that finalizers
- Meta (4/17) Jan 05 2018 I can't find the thread (it's a couple years old at this point, I
- 12345swordy (2/21) Jan 05 2018 Removing it is not the same thing as spiting them up.
- Meta (2/24) Jan 05 2018 I meant it as an addendum
- Jonathan M Davis (19/32) Jan 05 2018 Part of the problem with that is that if you stick a struct on the heap,...
I usually write my applications' main logic into one or more classes unless it can be avoided, and thus I often use ctors and dtors for initializing and cleaning up things. One of them (my engine) uses dtors for cleaning up things from a non-GC external library (SDL2, using the Derelict loader). If I close one of the apps I've written with them, it generates an access violation error within the SDL2 library. This doesn't happen with others, probably depending on what kind of resources I use. However, I just found a fix to the issue: if I manually call the dtor of the main logic after it exited from the main loop and remove the call for SDL2_QUIT(), there's no issues with SDL2, even the time it takes to quit it back to normal instead of the almost instant crash upon trying to close the application.
Jan 05 2018
On Friday, 5 January 2018 at 14:23:30 UTC, solidstate1991 wrote:I usually write my applications' main logic into one or more classes unless it can be avoided, and thus I often use ctors and dtors for initializing and cleaning up things.The problem with this is when the GC runs, it considers everything dead to have died at the same time - parent and child objects alike - and will run the destructors in whatever order is most convenient for the GC implementation. That means the SDL quit function may be called BEFORE other cleanup, leading to your access violation. Indeed, what you want to do is explicitly call things that need to be done in order... in order. Can't rely on the GC to call functions in any particular way.
Jan 05 2018
On Friday, January 05, 2018 14:29:41 Adam D. Ruppe via Digitalmars-d wrote:On Friday, 5 January 2018 at 14:23:30 UTC, solidstate1991 wrote:Either that or use structs on the stack instead of classes on the heap so that you're actually using destructors instead of finalizers. - Jonathan M DavisI usually write my applications' main logic into one or more classes unless it can be avoided, and thus I often use ctors and dtors for initializing and cleaning up things.The problem with this is when the GC runs, it considers everything dead to have died at the same time - parent and child objects alike - and will run the destructors in whatever order is most convenient for the GC implementation. That means the SDL quit function may be called BEFORE other cleanup, leading to your access violation. Indeed, what you want to do is explicitly call things that need to be done in order... in order. Can't rely on the GC to call functions in any particular way.
Jan 05 2018
On Friday, 5 January 2018 at 14:35:44 UTC, Jonathan M Davis wrote:On Friday, January 05, 2018 14:29:41 Adam D. Ruppe via Digitalmars-d wrote:There been discussions regarding spiting up the destruction and finalizers.[...]Either that or use structs on the stack instead of classes on the heap so that you're actually using destructors instead of finalizers. - Jonathan M Davis
Jan 05 2018
On Fri, Jan 05, 2018 at 03:26:03PM +0000, 12345swordy via Digitalmars-d wrote:On Friday, 5 January 2018 at 14:35:44 UTC, Jonathan M Davis wrote:[...]On Friday, January 05, 2018 14:29:41 Adam D. Ruppe via Digitalmars-d wrote:[...]Either that or use structs on the stack instead of classes on the heap so that you're actually using destructors instead of finalizers.There been discussions regarding spiting up the destruction and finalizers.Yeah, the GC does not guarantee any particular order that finalizers will be called. If you need to ensure a particular order, you'll need to either do it yourself, or use a refcounting scheme like RefCounted and set it up so that the last references go away in the right order. Lately, I've been moving towards using RefCounted for things that need deterministic destruction or things that need to be finalized in some specific order. The GC is more for objects that don't need any special action when they're collected. T -- Knowledge is that area of ignorance that we arrange and classify. -- Ambrose Bierce
Jan 05 2018
On Friday, 5 January 2018 at 15:26:03 UTC, 12345swordy wrote:On Friday, 5 January 2018 at 14:35:44 UTC, Jonathan M Davis wrote:I can't find the thread (it's a couple years old at this point, I think), but Andrei once proposed removing class destructors and met very heavy resistance so he dropped it.On Friday, January 05, 2018 14:29:41 Adam D. Ruppe via Digitalmars-d wrote:There been discussions regarding spiting up the destruction and finalizers.[...]Either that or use structs on the stack instead of classes on the heap so that you're actually using destructors instead of finalizers. - Jonathan M Davis
Jan 05 2018
On Friday, 5 January 2018 at 17:14:58 UTC, Meta wrote:On Friday, 5 January 2018 at 15:26:03 UTC, 12345swordy wrote:Removing it is not the same thing as spiting them up.On Friday, 5 January 2018 at 14:35:44 UTC, Jonathan M Davis wrote:I can't find the thread (it's a couple years old at this point, I think), but Andrei once proposed removing class destructors and met very heavy resistance so he dropped it.On Friday, January 05, 2018 14:29:41 Adam D. Ruppe via Digitalmars-d wrote:There been discussions regarding spiting up the destruction and finalizers.[...]Either that or use structs on the stack instead of classes on the heap so that you're actually using destructors instead of finalizers. - Jonathan M Davis
Jan 05 2018
On Friday, 5 January 2018 at 19:18:59 UTC, 12345swordy wrote:On Friday, 5 January 2018 at 17:14:58 UTC, Meta wrote:I meant it as an addendumOn Friday, 5 January 2018 at 15:26:03 UTC, 12345swordy wrote:Removing it is not the same thing as spiting them up.On Friday, 5 January 2018 at 14:35:44 UTC, Jonathan M Davis wrote:I can't find the thread (it's a couple years old at this point, I think), but Andrei once proposed removing class destructors and met very heavy resistance so he dropped it.On Friday, January 05, 2018 14:29:41 Adam D. Ruppe via Digitalmars-d wrote:There been discussions regarding spiting up the destruction and finalizers.[...]Either that or use structs on the stack instead of classes on the heap so that you're actually using destructors instead of finalizers. - Jonathan M Davis
Jan 05 2018
On Friday, January 05, 2018 15:26:03 12345swordy via Digitalmars-d wrote:On Friday, 5 January 2018 at 14:35:44 UTC, Jonathan M Davis wrote:Part of the problem with that is that if you stick a struct on the heap, its destructor becomes a finalizer. And for that matter, a class' finalizer becomes a destructor if you put in on the stack with scope or std.typecons.scoped. So, while you generally code as if structs have destructors and classes have finalizers, that distinction isn't entirely true. And if destructors and finalizers are different, then suddenly you have to implement two different functions to do more or less the same thing. That wouldn't be all bad, because on some level, it would force folks to consider the consequences of putting stuff on the heap vs the stack with regards to destruction, but in practice, it probably would result in folks either just usually implementing one and cause problems because of that or blindly making one call the other or make both call a common function to shared code. It could very well be that changing how destructors and finalizers are declared should be done, but it's not exactly a straightforward issue, and we'd need to come up with something that was clearly better for it to make sense to make a change. - Jonathan M DavisOn Friday, January 05, 2018 14:29:41 Adam D. Ruppe via Digitalmars-d wrote:There been discussions regarding spiting up the destruction and finalizers.[...]Either that or use structs on the stack instead of classes on the heap so that you're actually using destructors instead of finalizers. - Jonathan M Davis
Jan 05 2018