want to confirm: gc will not free a non-gc-allocated field of a gc-allocated object?

H. S. Teoh hsteoh at qfbox.info
Mon Jun 6 22:34:55 UTC 2022


On Mon, Jun 06, 2022 at 10:18:08PM +0000, mw via Digitalmars-d-learn wrote:
> Hi,
> 
> Suppose I have this code:
> 
> ```
> class GCAllocated {
>   float[] data;
> 
>   this() {
>     // non-gc-allocated field
>     this.data = cast(float[])(core.stdc.stdlib.malloc(nBytes)[0 .. nBytes]);
>   }
> }
> 
> void foo() {
>   auto obj = new GCAllocated();  // gc-allocated owning object
>   ...
> }
> 
> ```
> 
> So when `obj` is cleanup by the GC, obj.data won't be freed by the GC:
> because the `data` is non-gc-allocated (and it's allocated on the
> non-gc heap), the GC scanner will just skip that field during a
> collection scan. Is this understanding correct?
> 
> I need this behavior for a special purpose, so I want to confirm it.
[...]

Short answer: yes, the GC will not do anything with that field.

Long answer: even if the GC wanted to do something about that field, how
could it? It has no information about how it was allocated. As far as
the GC is concerned, it's just a pointer + size pair, just like any
other array, and the pointer happens to point outside of GC-allocated
memory. Beyond that, the GC knows nothing else about the pointer. Is it
allocated by malloc? Is it pointing to static memory? Is it some
user-defined custom allocator? Is it some random garbage value?  Who
knows. The GC knows nothing about the pointer, so it conservatively
ignores it.

On a more general implementational note, D's GC is conservative, meaning
that if an aligned pointer-sized value looks like it might be a pointer
value, the GC will assume, erring on the side of being overly cautious,
that it *is* a pointer value, and mark any GC memory that it might
happen to point to as live.  The value could be an int or long, and the
GC wouldn't know any better. (More recent precise implementations may
skip some of these false positives, though.)  The same principle
applies, though: if the pointer has a value that the GC doesn't know
about (i.e., doesn't point to any of the known GC blocks) then the GC
will conservatively just ignore it.


T

-- 
Give a man a fish, and he eats once. Teach a man to fish, and he will sit forever.


More information about the Digitalmars-d-learn mailing list