Question to GC experts: NO_SCAN for a part of the block
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Mon Jun 5 06:11:25 PDT 2017
On 6/4/17 5:57 AM, Stanislav Blinov wrote:
> On Sunday, 4 June 2017 at 09:38:45 UTC, ag0aep6g wrote:
>
>>> Should this work, and if not, why?
>>
>> As far as I can tell, the `addRange` call works correctly, but maybe
>> too well in a sense. It keeps the `new`ed `C`s alive as long as
>> `arrays3.Cs` has pointers to them. And `arrays3.Cs` has those pointers
>> until the very end.
>
> Yeah, after playing around with the code a bit, shuffling the calls,
> making new allocations, etc., I saw those dtors indeed being run. I was
> just expecting the behavior to be the same as for normal 'new'ed arrays,
> but I guess there are nuances.
>
>> If you add `GC.removeRange(arrays3.Cs.ptr);` at the of `main`, the
>> dtors show up.
>
> Yeah, well, calling it manually sort of defeats the purpose :)
adding a range marks it as having pointers to scan, AND stores a
reference to that array, so it won't be GC collected (nor will anything
it points to). The intention is for it to be used on non-GC memory, like
C malloc'd memory, where it doesn't matter that the GC is pointing at it.
I would say that you are better off allocating 2 arrays -- one with
NO_SCAN where you put your non-pointer-containing data, and one without
the flag to put your other data. This is similar to your "selective"
function, but instead of allocating 1 array, with a tuple of slices into
it, just allocate 2 arrays and return the tuple of those 2 arrays.
In my dcollections library, the allocator I use uses malloc for
non-pointer containing arrays, and GC for everything that could contain
pointers, and then divvy up the array into the exact sizes I want. Works
quite well, but the dtor of the container needs to deallocate the
malloc'd one.
-Steve
More information about the Digitalmars-d
mailing list