www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - An idea for GC and freeing of resources without finalization

reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
Yesterday I got an idea of how we could remove destructors from 
classes and still free resources in situations where you rely on 
having a GC. I am sure some high level languages do something 
similar in their runtimes.

So the basic idea is that all resource handles is given a special 
type so that when you trace live objects you also record live 
handles (setting a bit in a bit array).

Then a resource manager (part of the GC infrastructure) can tell 
that some resource handles are no longer reachable and free them 
based on the dependency chains it has recorded.

E.g. opening a database might be one resource, opening queries on 
that database might be another set of resources that depends on 
the database. When query-handles are no longer reachable they get 
freed. When there are no resources depending on the database and 
no handle to the database is reachable the database is closed.

What is needed then is way to create resource managers and hook 
them up to the GC infrastructure. All allocation of resources 
happen through those managers.

The advantage of this is that one can just free memory instantly 
completely disregarding any handles that are being wiped out.

And there is no need to write destructor code.

But the lack of precise scanning is still a problem.
Jun 17 2021
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
Alternatively we could make scope actually work for us.

With scope as a storage class we can assume that there is an owning 
point on the stack for a give handle (the language nor druntime is aware 
of the handle itself).

When that owning point goes out of scope, either the container gets 
destroyed or an operator overload gets called saying scope ends now!

Along with another operator overload that allows you to return a 
seperete reference to that handle when you try to escape scope, done!
Jun 17 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 17 June 2021 at 10:50:41 UTC, rikki cattermole wrote:
 Alternatively we could make scope actually work for us.

 With scope as a storage class we can assume that there is an 
 owning point on the stack for a give handle (the language nor 
 druntime is aware of the handle itself).

 When that owning point goes out of scope, either the container 
 gets destroyed or an operator overload gets called saying scope 
 ends now!

 Along with another operator overload that allows you to return 
 a seperete reference to that handle when you try to escape 
 scope, done!
I am thinking that one does not exclude the other! :-D So you would encourage people to free up resources explicitly, to avoid frequent collection, but maybe you want to quickly tear down a task, or maybe an exception was thrown in such a way that a resource handle was lost (e.g. in a constructor). Then you can still assume that the resource will be collected. Either way, since all objects are traced anyway, and resource handles are fairly rare, it won't cost much to tag them when scanning pointers. I think the amortized cost would be close to zero!? The core focus is to speed up collection, making source code cleaner and execution more robust. But yes, freeing resources early should be the main strategy, but I think people will fail to do this in more complicated patterns where resources are involved in more async code that stuff resources handles into a graph of some sort.
Jun 17 2021
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 17/06/2021 11:02 PM, Ola Fosheim Grøstad wrote:
 I am thinking that one does not exclude the other! :-D
Having the GC act as a backup wouldn't be a bad thing! More complex patterns shouldn't matter. Once you have an owning point on the stack, which may not be explicitly known (as long as the scope rules are meet, you should be able to figure it out locally). But yes, exceptions worry me.
Jun 17 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 17 June 2021 at 11:14:05 UTC, rikki cattermole wrote:
 Having the GC act as a backup wouldn't be a bad thing!
Exactly, if it is there anyway, why not use it?
 More complex patterns shouldn't matter. Once you have an owning 
 point on the stack, which may not be explicitly known (as long 
 as the scope rules are meet, you should be able to figure it 
 out locally).
That won't work if you have many async connections. Then they are stored in a graph on the heap. My goal is to get rid of the need for finalizers and destructors, to speed up collection and make code easier to write. So, for instance, if a fileobject is constructed with the file path and then has an open() and close() method. Then you could in Python-like fashion do something like ``` with Url("some/path/file.txt") as f { … f.read() … } ```` Which basically calls f.open() then waits for the data to be ready and continues, then calls f.close(). Or you could ``` store_on_heap_read_when_ready(Url("some/path/file.txt").open()) ``` Not necessarily this syntax, but you get the idea.
Jun 17 2021
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 18/06/2021 12:02 AM, Ola Fosheim Grøstad wrote:
 That won't work if you have many async connections. Then they are stored 
 in a graph on the heap. My goal is to get rid of the need for finalizers 
 and destructors, to speed up collection and make code easier to write.
async like you are describing isn't limited to one thread, therefore yeah, need a different solution.
Jun 17 2021