Understanding the GC

monarch_dodra monarchdodra at gmail.com
Thu Jan 31 23:07:00 PST 2013


On Thursday, 31 January 2013 at 23:53:26 UTC, Steven 
Schveighoffer wrote:
>
> A destructor should ONLY be used to free up resources other 
> than GC allocated memory.  Because of that, it's generally not 
> used.
>
> It should be used almost as a "last resort".
>
> For example, a class that holds a file descriptor should have 
> both a destructor (which closes the descriptor) and a manual 
> close method.  The former is to clean up the file descriptor in 
> case nobody thought to close it manually before all references 
> were gone, and the latter is because file descriptors are not 
> really managed by the GC, and so should be cleaned up when they 
> are no longer used.
>
> This kind of gives us a paradox, since the class is managed via 
> the GC, how do you know it's no longer used (that is, how do 
> you know this is the last reference to it)?  That is really up 
> to the application design.  But I wouldn't recommend relying on 
> the GC to clean up your descriptors.
>
> -Steve

I've actually run into this very issue: I was iterating on files, 
opening them, and placing the descriptor in GC-allocated RAII 
data. I can't remember if class or struct, but not a big issue. 
Come to think about it, I think I was using "File", but 
allocating them because I thought they were classes `auto f = new 
File("my file", "r")`.

After running for a second, my program halts, because an 
exception was thrown trying to open a new file:
"Cannot open file: Too many open file handles".

It was basically: Sure, the GC will destroy and close files for 
you... if you forget... eventually...

I ended up closing them in scope(exit) blocks. Problem 
immediately solved. Or I could have stopped allocating my File's 
on the heap.

Either way, it shows you shouldn't rely on the GC for 
deterministic destruction.


More information about the Digitalmars-d-learn mailing list