Understanding the GC

monarch_dodra monarchdodra at gmail.com
Fri Feb 1 07:46:11 PST 2013


On Friday, 1 February 2013 at 15:37:25 UTC, Steven Schveighoffer 
wrote:
> On Fri, 01 Feb 2013 02:07:00 -0500, monarch_dodra 
> <monarchdodra at gmail.com> wrote:
>
>> 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.
>
> Actually, that's a different problem.  File is a struct, and 
> structs do NOT have their destructor run by the GC.  Only 
> Objects do.
>
> This is a GC limitation, since structs do not contain a pointer 
> to their typeinfo like classes do, and there is no provision 
> for storing a pointer to the typeinfo of a block.  It could be 
> fixed by a more precise GC.  AIUI, we have something like that 
> coming, but I've been hearing that for more than a year ;)
>
> -Steve

Oh. Wow. That's news to me.

I'd say as long as you don't new your structs, you are fine, but 
apparently, dynamic arrays don't clean up after themselves either 
(!) That's a whole other ballgame...

That's quite scary. It brings back into question a few of my 
implementations...


More information about the Digitalmars-d-learn mailing list