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.