Garbage collector collects live objects

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Dec 9 08:53:02 PST 2014


On 12/9/14 11:17 AM, ketmar via Digitalmars-d-learn wrote:
> On Tue, 09 Dec 2014 14:52:53 +0000
> Ruslan Mullakhmetov via Digitalmars-d-learn
> <digitalmars-d-learn at puremagic.com> wrote:
>
>> On Tuesday, 9 December 2014 at 14:23:06 UTC, Steven Schveighoffer
>> wrote:
>>> On 12/9/14 8:54 AM, Ruslan Mullakhmetov wrote:
>>>>
>>>> Hi,
>>>>
>>>> I experience very strange problem: GC somehow collects live
>>>> objects.
>>>>
>>>> I found it because i got segfaults. After debugging and
>>>> tracing i found
>>>> this is because of accessing not allocated memory.
>>>>
>>>> I did the following checks:
>>>>
>>>> - added to some class invariant check for access to suspicious
>>>> members
>>>> with assertion
>>>>
>>>> assert(GC.addrOf(cast(void*)x) !is null);
>>>>
>>>>
>>>> where it fails DETERMINISTICALLY at some point
>>>>
>>>> - printing address of allocated classes where i observe the
>>>> following
>>>> pattern
>>>>
>>>> -> ctor
>>>>       check
>>>>       check
>>>>       check
>>>> <- dtor
>>>>       check (fails)
>>>>
>>>> could anybody advice me with something? I got really
>>>> frustrated by this
>>>> strange behaviour which i can not fix right now.
>>>>
>>>> key observations:
>>>> - it is deterministically behaviour (what gets me even more
>>>> confused
>>>> cause GC collections as far as i know runs from time to time)
>>>> - i do not play with pointers optimisation like hiding its in
>>>> ints or
>>>> floats.
>>>> - i operate with large uniformly distributed (video) data in
>>>> memory
>>>> where pointer like patterns may occur. but this is not the
>>>> case cause
>>>> (1) it brings at worst long living objects (2) input sequence
>>>> constant
>>>> but allocated pointers each run different.
>>>>
>>>
>>> A random guess, since you haven't posted any code, are you
>>> accessing GC resources inside a destructor? If so, that is not
>>> guaranteed to work. A class destructor, or a destructor of a
>>> struct that is contained inside a class, can only be used to
>>> destroy NON-GC resources.
>>>
>>> If you want more help, you need to post some code. Something
>>> that minimally causes the issue would be good.
>>>
>>> -Steve
>>
>> No, there is no accessing GC resources in dtors.
>>
>> the only usage of dtor in one class is
>>
>> 	~this()
>> 	{
>> 		_file.close();
>> 	}
>>
>> where _file is of type std.file.File
>>
>> i'll try to extract problem to any observable source code but all
>> my previous attempts lead to problem being diminish.
>
> that file can be already finalized. please remember that `~this()` is
> more a finalizer than destructor, and it's called on *dead* object.
> here this means that any other object in your object (including
> structs) can be already finalized at the time GC decides to call your
> finalizer.

File is specially designed (although it's not perfect) to be able to 
close in the GC. Its ref-counted payload is placed on the C heap to 
allow access during finalization.

That being said, you actually don't need to write the above in the class 
finalizer, _file's destructor will automatically be called.

> just avoid "destructors" unless you *really* need that. in your case
> simply let GC finalize your File, don't try to help GC. this is not C++
> (or any other language without GC) and "destructors" aren't destructing
> anything at all. "destructors" must clean up the things that GC cannot
> (malloc()'ed memory, for example), and nothing else.
>

Good advice ;)

I would say other than library writers, nobody should ever write a class 
dtor.

-Steve


More information about the Digitalmars-d-learn mailing list