Memory management and local GC?

Steven Schveighoffer schveiguy at gmail.com
Mon Nov 2 14:44:08 UTC 2020


On 11/2/20 8:23 AM, IGotD- wrote:
> On Monday, 2 November 2020 at 12:28:34 UTC, Steven Schveighoffer wrote:
>>
>> What is the problem with allocating them shared in the first place? 
>> Ideally, you will NEVER transfer thread-local data to a shared context.
>>
> 
> How would you distinguish between global and local GC allocated data in 
> the language? Many times you need GC allocated data that can be used 
> globally, so we need new D local key words like "localnew" or "globalnew".

It's possible to allocate without using `new`.

Something like:

GlobalPool.allocate!T(ctor_args) // returns shared(T)*

> Then since we are talking on GC operations on GC allocated memory should 
> be disallowed between threads but what mechanisms does D have in order 
> to prevent pure access to that data? Only disallowing GC operations is 
> just going half way as I see it.

D has shared qualifier, which indicates whether any other thread has 
access to it.

This is kind of the lynch pin of all these schemes. Without that 
enforced properly, you can't build anything.

But with it enforced properly, you have options.

There are still problems. Like immutable is implicitly shared. Or you 
can have a type which contains both shared and unshared members, where 
is that allocated?

> 
> In general these multithreaded allocators usually use "stages" meaning 
> that they have several memory regions to play with hoping that it will 
> reduce mutex locking. Usually there is an upper limit how many stages 
> you want before there isn't any performance advantage. Also tracking 
> stages requires resources itself. If D would open up such stage for 
> every thread, there will be a new stage for every thread with no upper 
> limit. This will require extra metadata as well as a new region. I guess 
> that implementation wise this will be complicated and also require even 
> more memory than it does today.
> 

You don't necessarily need to assign regions to threads. You could 
potentially use one region and assign different pools to different 
threads. If the GC doesn't need to scan shared data at all, then it's a 
matter of skipping the pools that aren't interesting to your local GC.

As long as a pool never gets moved to another thread, you can avoid most 
locking.

-Steve


More information about the Digitalmars-d mailing list