www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - GC Destruction Order

reply bitwise <bitwise.pvt gmail.com> writes:

the containing object.

Example:

class Stuff
{
     Class1 thing1;
     Class2 thing2;

     ~Stuff() {
         thing1.DoSomeFinalization();  //  [1]
     }
}

I forget what the exact behavior was, but basically, [1] is unsafe because  
it may have already been destructed/freed by the time ~Stuff() is called.

Is this also true for D?

   Bit
May 19 2015
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
May 19 2015
parent reply bitwise <bitwise.pvt gmail.com> writes:
On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe  
<destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve. I have heard about attempts to add precise GC to D though... would precise GC address this problem in some way? Bit
May 19 2015
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/19/15 2:37 PM, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It's actually quite impossible for the GC to know what pointers are "owning" pointers and what ones are not. And you could never have ownership cycles. You could use some version of malloc/free to do it. But you have to take care of GC references inside that malloc'd block.
 I have heard about attempts to add precise GC to D though... would
 precise GC address this problem in some way?
No. Precise scanning just (potentially) cuts down on scanning time, and avoids false pointers. -Steve
May 19 2015
parent bitwise <bitwise.pvt gmail.com> writes:
On Tue, 19 May 2015 14:55:55 -0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On 5/19/15 2:37 PM, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It's actually quite impossible for the GC to know what pointers are "owning" pointers and what ones are not. And you could never have ownership cycles. You could use some version of malloc/free to do it. But you have to take care of GC references inside that malloc'd block.
 I have heard about attempts to add precise GC to D though... would
 precise GC address this problem in some way?
No. Precise scanning just (potentially) cuts down on scanning time, and avoids false pointers. -Steve
Ok, thanks for the quick answers =D Bit
May 19 2015
prev sibling parent reply "rsw0x" <anonymous anonymous.com> writes:
On Tuesday, 19 May 2015 at 18:37:31 UTC, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe 
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It actually does, check out RefCounted!T and Unique!T in std.typecons. They're sort of limited right now but undergoing a major revamp in 2.068.
May 19 2015
next sibling parent reply "Namespace" <rswhite4 gmail.com> writes:
On Tuesday, 19 May 2015 at 19:36:23 UTC, rsw0x wrote:
 On Tuesday, 19 May 2015 at 18:37:31 UTC, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe 
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It actually does, check out RefCounted!T and Unique!T in std.typecons. They're sort of limited right now but undergoing a major revamp in 2.068.
By the way: when is 2.068 released?
May 19 2015
parent reply "rsw0x" <anonymous anonymous.com> writes:
On Tuesday, 19 May 2015 at 19:45:38 UTC, Namespace wrote:
 On Tuesday, 19 May 2015 at 19:36:23 UTC, rsw0x wrote:
 On Tuesday, 19 May 2015 at 18:37:31 UTC, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe 
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It actually does, check out RefCounted!T and Unique!T in std.typecons. They're sort of limited right now but undergoing a major revamp in 2.068.
By the way: when is 2.068 released?
"After dconf" http://forum.dlang.org/thread/5554D763.1080308 dawg.eu#post-5554D763.1080308:40dawg.eu
May 19 2015
parent reply "Namespace" <rswhite4 gmail.com> writes:
On Tuesday, 19 May 2015 at 20:02:07 UTC, rsw0x wrote:
 On Tuesday, 19 May 2015 at 19:45:38 UTC, Namespace wrote:
 On Tuesday, 19 May 2015 at 19:36:23 UTC, rsw0x wrote:
 On Tuesday, 19 May 2015 at 18:37:31 UTC, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe 
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It actually does, check out RefCounted!T and Unique!T in std.typecons. They're sort of limited right now but undergoing a major revamp in 2.068.
By the way: when is 2.068 released?
"After dconf" http://forum.dlang.org/thread/5554D763.1080308 dawg.eu#post-5554D763.1080308:40dawg.eu
I thought the new releases would come faster.
May 19 2015
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/19/15 4:16 PM, Namespace wrote:
 On Tuesday, 19 May 2015 at 20:02:07 UTC, rsw0x wrote:
 "After dconf"
 http://forum.dlang.org/thread/5554D763.1080308 dawg.eu#post-5554D763.1080308:40dawg.eu
I thought the new releases would come faster.
They should. This is an exception. Read the thread quoted above. -Steve
May 19 2015
prev sibling parent reply bitwise <bitwise.pvt gmail.com> writes:
On Tue, 19 May 2015 15:36:21 -0400, rsw0x <anonymous anonymous.com> wrote:

 On Tuesday, 19 May 2015 at 18:37:31 UTC, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe  
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It actually does, check out RefCounted!T and Unique!T in std.typecons. They're sort of limited right now but undergoing a major revamp in 2.068.
Any idea what the plans are?. Does RefCounted become thread safe? Correct me if I'm wrong though, but even if RefCounted itself was thread-safe, RefCounted objects could still be placed in classes, at which point you might as well use a GC'ed class instead, because you'd be back to square-one with your destructor racing around on some random thread. I'm finding it hard to be optimistic about the memory model of D. The idea of marking absolutely everything in your program with " nogc" just to make it safe is ludicrous. Something like this would be a little more reasonable, but I see no discussions about it: nogc module my_module; or nogc class Something{} DIP74 seems like it would improve the situation a lot, but wouldn't work as expected as long as any other class that may contain it could be GC'ed. This also seems like a monumental undertaking that won't actually be implemented for years, if at all. I'm hoping someone will correct me here, because other than the memory model, D seems like a very well designed language. Bit
May 19 2015
next sibling parent reply "rsw0x" <anonymous anonymous.com> writes:
On Tuesday, 19 May 2015 at 21:07:52 UTC, bitwise wrote:
 On Tue, 19 May 2015 15:36:21 -0400, rsw0x 
 <anonymous anonymous.com> wrote:

 On Tuesday, 19 May 2015 at 18:37:31 UTC, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe 
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It actually does, check out RefCounted!T and Unique!T in std.typecons. They're sort of limited right now but undergoing a major revamp in 2.068.
Any idea what the plans are?. Does RefCounted become thread safe? Correct me if I'm wrong though, but even if RefCounted itself was thread-safe, RefCounted objects could still be placed in classes, at which point you might as well use a GC'ed class instead, because you'd be back to square-one with your destructor racing around on some random thread.
I don't understand what you're asking here. If you hold a RefCounted resource in a GC managed object, yes, it will be tied to the GC object's lifetime. With your avoidance of the GC, I feel like you were lied to by a C++ programmer that reference counting is the way to do all memory management, when in reality reference counting is dog slow and destroys your cache locality(esp. without compiler support.) Reference counting is meant to be used where you need absolute control over a resource's lifetime(IMHO,) not as a general purpose memory management tool. Bye.
May 19 2015
parent bitwise <bitwise.pvt gmail.com> writes:
On Tue, 19 May 2015 17:52:36 -0400, rsw0x <anonymous anonymous.com> wrote:

 On Tuesday, 19 May 2015 at 21:07:52 UTC, bitwise wrote:
 Any idea what the plans are?. Does RefCounted become thread safe?

 Correct me if I'm wrong though, but even if RefCounted itself was  
 thread-safe, RefCounted objects could still be placed in classes, at  
 which point you might as well use a GC'ed class instead, because you'd  
 be back to square-one with your destructor racing around on some random  
 thread.
I don't understand what you're asking here. If you hold a RefCounted resource in a GC managed object, yes, it will be tied to the GC object's lifetime. With your avoidance of the GC, I feel like you were lied to by a C++ programmer that reference counting is the way to do all memory management, when in reality reference counting is dog slow and destroys your cache locality(esp. without compiler support.) Reference counting is meant to be used where you need absolute control over a resource's lifetime(IMHO,) not as a general purpose memory management tool.
Thanks for confirming, but given your apparent tendency toward pinhole view points, it's unsurprising that you don't understand what I'm asking. Bit
May 19 2015
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/19/15 5:07 PM, bitwise wrote:
 On Tue, 19 May 2015 15:36:21 -0400, rsw0x <anonymous anonymous.com> wrote:

 On Tuesday, 19 May 2015 at 18:37:31 UTC, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It actually does, check out RefCounted!T and Unique!T in std.typecons. They're sort of limited right now but undergoing a major revamp in 2.068.
Any idea what the plans are?. Does RefCounted become thread safe? Correct me if I'm wrong though, but even if RefCounted itself was thread-safe, RefCounted objects could still be placed in classes, at which point you might as well use a GC'ed class instead, because you'd be back to square-one with your destructor racing around on some random thread.
With the current GC, yes. RefCounted needs to be thread safe in order to use it. But if we change the GC, we could ensure destructors are only called in the thread they were created in (simply defer destructors until the next GC call in that thread).
 I'm finding it hard to be optimistic about the memory model of D.

 The idea of marking absolutely everything in your program with " nogc"
 just to make it safe is ludicrous.
That makes no sense, the GC is not unsafe. -Steve
May 19 2015
parent reply bitwise <bitwise.pvt gmail.com> writes:
On Tue, 19 May 2015 18:47:26 -0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On 5/19/15 5:07 PM, bitwise wrote:
 On Tue, 19 May 2015 15:36:21 -0400, rsw0x <anonymous anonymous.com>  
 wrote:

 On Tuesday, 19 May 2015 at 18:37:31 UTC, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It actually does, check out RefCounted!T and Unique!T in std.typecons. They're sort of limited right now but undergoing a major revamp in 2.068.
Any idea what the plans are?. Does RefCounted become thread safe? Correct me if I'm wrong though, but even if RefCounted itself was thread-safe, RefCounted objects could still be placed in classes, at which point you might as well use a GC'ed class instead, because you'd be back to square-one with your destructor racing around on some random thread.
With the current GC, yes. RefCounted needs to be thread safe in order to use it. But if we change the GC, we could ensure destructors are only called in the thread they were created in (simply defer destructors until the next GC call in that thread).
This seems like it could result in some destructors being delayed indefinitely.
 I'm finding it hard to be optimistic about the memory model of D.

 The idea of marking absolutely everything in your program with " nogc"
 just to make it safe is ludicrous.
That makes no sense, the GC is not unsafe. -Steve
Maybe I worded that incorrectly, but my point is that when you're running with the GC disabled, you should only use methods marked with nogc if you want to make sure your code doesn't leak right? that's a lot of attributes O_O Bit
May 19 2015
next sibling parent reply bitwise <bitwise.pvt gmail.com> writes:
On Tue, 19 May 2015 19:03:02 -0400, bitwise <bitwise.pvt gmail.com> wrote:
 Maybe I worded that incorrectly, but my point is that when you're  
 running with the GC disabled, you should only use methods marked with  
  nogc if you want to make sure your code doesn't leak right? that's a  
 lot of attributes O_O

    Bit
....which is why I am asking if there are any plans to implement something like nogc for entire modules or classes. Bit
May 19 2015
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 19 May 2015 at 23:10:21 UTC, bitwise wrote:
 ....which is why I am asking if there are any plans to 
 implement something like  nogc for entire modules or classes.
At the top: nogc: <stuff here> Gotta do it inside the class too i think.
May 19 2015
parent reply bitwise <bitwise.pvt gmail.com> writes:
On Tue, 19 May 2015 19:16:14 -0400, Adam D. Ruppe  
<destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 23:10:21 UTC, bitwise wrote:
 ....which is why I am asking if there are any plans to implement  
 something like  nogc for entire modules or classes.
At the top: nogc: <stuff here> Gotta do it inside the class too i think.
Thanks! this seems to work too: nogc { <stuff> } I think this is still a problem though: struct StackThing { ~this() { writeln("where am I?"); } } class HeapThing{ StackThing thing; } HeapThing thing = new HeapThing(); Basically, I can't design a struct and be sure the destructor will be called on the same thread as where it went out of scope. I hope I'm wrong and DIP74 comes soon =/ Bit
May 19 2015
parent reply "Kagamin" <spam here.lot> writes:
On Tuesday, 19 May 2015 at 22:15:18 UTC, bitwise wrote:
 Thanks for confirming, but given your apparent tendency toward 
 pinhole view points, it's unsurprising that you don't 
 understand what I'm asking.
And what you're asking. Just for the record: C++ memory management techniques are not designed to work in GC environment. On Wednesday, 20 May 2015 at 03:44:58 UTC, bitwise wrote:
 Basically, I can't design a struct and be sure the destructor 
 will be called on the same thread as where it went out of scope.
If your resource finalization code has some specific threading requirements, you implement those yourself in a way your code requires it. Or instead freeing resources normally in due time.
May 20 2015
parent reply "bitwise" <bitwise.pvt gmail.com> writes:
On Wednesday, 20 May 2015 at 08:01:46 UTC, Kagamin wrote:
 On Tuesday, 19 May 2015 at 22:15:18 UTC, bitwise wrote:
 Thanks for confirming, but given your apparent tendency toward 
 pinhole view points, it's unsurprising that you don't 
 understand what I'm asking.
And what you're asking. Just for the record: C++ memory management techniques are not designed to work in GC environment.
Yes, but D claims to support manual memory management. It seems to get second class treatment though. I'm pretty sure I can
 On Wednesday, 20 May 2015 at 03:44:58 UTC, bitwise wrote:
 Basically, I can't design a struct and be sure the destructor 
 will be called on the same thread as where it went out of 
 scope.
If your resource finalization code has some specific threading requirements, you implement those yourself in a way your code requires it. Or instead freeing resources normally in due time.
AFAIK D does not provide any built in functionality like Objective-C's 'runOnMainThread', which makes this a painful option.
May 20 2015
parent reply "Kagamin" <spam here.lot> writes:
On Wednesday, 20 May 2015 at 13:54:29 UTC, bitwise wrote:
 Yes, but D claims to support manual memory management. It seems 
 to get second class treatment though.
It's WIP. There were thoughts to run finalizers on the thread where the object was allocated (I doubt it's a good idea, though). Anyway, if you're doing manual memory management, how GC popped up? If you have your manual memory managed with GC, it means you have a memory leak: manually managed memory shouldn't become garbage without being freed. I suppose it will be a long way before D rediscovers .net practices.

I use Marshal.AllocHGlobal.
 Basically, I can't design a struct and be sure the destructor 
 will be called on the same thread as where it went out of 
 scope.
If your resource finalization code has some specific threading requirements, you implement those yourself in a way your code requires it. Or instead freeing resources normally in due time.
AFAIK D does not provide any built in functionality like Objective-C's 'runOnMainThread', which makes this a painful option.
You asked for destructor being called on the thread where it went out of scope, which is not necessarily the main thread.
May 20 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/20/15 11:09 AM, Kagamin wrote:
 On Wednesday, 20 May 2015 at 13:54:29 UTC, bitwise wrote:
 Yes, but D claims to support manual memory management. It seems to get
 second class treatment though.
It's WIP. There were thoughts to run finalizers on the thread where the object was allocated (I doubt it's a good idea, though).
It's essential for lockless thread-local programming. At this moment, a thread-local-only heap pointer must deal with multi-threading issues simply because destructors can run on another thread, even though the reference is thread-local. The biggest example right now is reference-counted structures such as std.stdio.File. The absolute best part about the shared qualifier is the lack of shared qualifier -- you can be certain something isn't shared if it doesn't have shared attached to it. Right now, even in that case, you still have to worry about RAII objects being destroyed in other threads. We shouldn't have to worry about that. -Steve
May 21 2015
next sibling parent reply "Kagamin" <spam here.lot> writes:
On Thursday, 21 May 2015 at 12:33:33 UTC, Steven Schveighoffer 
wrote:
 At this moment, a thread-local-only heap pointer must deal with 
 multi-threading issues simply because destructors can run on 
 another thread, even though the reference is thread-local. The 
 biggest example right now is reference-counted structures such 
 as std.stdio.File.
You mean the reference counting part?
May 21 2015
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/21/15 8:40 AM, Kagamin wrote:
 On Thursday, 21 May 2015 at 12:33:33 UTC, Steven Schveighoffer wrote:
 At this moment, a thread-local-only heap pointer must deal with
 multi-threading issues simply because destructors can run on another
 thread, even though the reference is thread-local. The biggest example
 right now is reference-counted structures such as std.stdio.File.
You mean the reference counting part?
Yes, if you put a File as a class member, the destructor of the class would call the File's destructor, which could be run in any thread. Since File is a reference counted wrapper, the destructor decrements the reference count and possibly closes the file. The whole operation must be atomic if we are spread across threads. But if you only ever access that containing class in a local thread, you are paying the cost of locking (or at least atomic decrement) for all reference counts on that file, for very little reason. Especially if the File doesn't live in a heap object (dtor doesn't know where it's being called from). -Steve
May 21 2015
prev sibling parent "Kagamin" <spam here.lot> writes:
On Thursday, 21 May 2015 at 12:33:33 UTC, Steven Schveighoffer 
wrote:
 At this moment, a thread-local-only heap pointer must deal with 
 multi-threading issues simply because destructors can run on 
 another thread, even though the reference is thread-local. The 
 biggest example right now is reference-counted structures such 
 as std.stdio.File.
Just for the record: .net doesn't use reference counting for system resources like files, it works fine, such resources usually have well-defined ownership.
May 21 2015
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/19/15 7:03 PM, bitwise wrote:
 On Tue, 19 May 2015 18:47:26 -0400, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:

 On 5/19/15 5:07 PM, bitwise wrote:
 On Tue, 19 May 2015 15:36:21 -0400, rsw0x <anonymous anonymous.com>
 wrote:

 On Tuesday, 19 May 2015 at 18:37:31 UTC, bitwise wrote:
 On Tue, 19 May 2015 14:19:30 -0400, Adam D. Ruppe
 <destructionator gmail.com> wrote:

 On Tuesday, 19 May 2015 at 18:15:06 UTC, bitwise wrote:
 Is this also true for D?
Yes. The GC considers all the unreferenced memory dead at the same time and may clean up the class and its members in any order.
Ugh... I was really hoping D had something better up it's sleeve.
It actually does, check out RefCounted!T and Unique!T in std.typecons. They're sort of limited right now but undergoing a major revamp in 2.068.
Any idea what the plans are?. Does RefCounted become thread safe? Correct me if I'm wrong though, but even if RefCounted itself was thread-safe, RefCounted objects could still be placed in classes, at which point you might as well use a GC'ed class instead, because you'd be back to square-one with your destructor racing around on some random thread.
With the current GC, yes. RefCounted needs to be thread safe in order to use it. But if we change the GC, we could ensure destructors are only called in the thread they were created in (simply defer destructors until the next GC call in that thread).
This seems like it could result in some destructors being delayed indefinitely.
That's already the case.
 I'm finding it hard to be optimistic about the memory model of D.

 The idea of marking absolutely everything in your program with " nogc"
 just to make it safe is ludicrous.
That makes no sense, the GC is not unsafe.
Maybe I worded that incorrectly, but my point is that when you're running with the GC disabled, you should only use methods marked with nogc if you want to make sure your code doesn't leak right? that's a lot of attributes O_O
OK, I see your point. Yes, you need nogc to not leak. The point of nogc was to ensure machine-checkable prevention of GC calls. The idea is to put nogc on main(), and then all your calls will have to be nogc. Where it absolutely comes in handy is compiler generated GC calls that can be unexpected (e.g. closures). But I'd still recommend not disabling the GC, as that is redundant, and having a stray GC call will not leak if something somehow (roguely) uses the GC (there are ways to do this). Alternatively, you can run a collection at opportune times just in case. It means you have to live with a subset of the language, and phobos cannot support you 100%. We are working to ensure that it's nogc as much as possible. -Steve
May 21 2015