|Final Garbage Collection
|Page 1 of 1|
|Author:||bavoha [ Tue Dec 20, 2016 2:31 pm ]|
|Post subject:||Final Garbage Collection|
The machine does a final garbage-collection when the machine (gmMachine) is destroyed. Good thing!
However, from what I see it does not respect dependecies at that point anymore. It - more or less - randomly destroys my user-objects without handling dependencies between those.
Is my observation correct?
This sometimes is a problem, for example a window gets destroyed before the assets are freed. Or a sound-buffer is destroyed before the sound-device object is done (thus the sound-device tries to play a destroyed buffer).
What I expect from a final garbage-collection is, that is first destroys the global-table and then continues from there. I guess that would do the trick. Maybe after that destroy the rest of the remaining stuff.
Is a fix possible (I would volunteer in fixing, but probably need some hints)?
|Author:||Greg [ Wed Dec 21, 2016 9:40 am ]|
|Post subject:||Re: Final Garbage Collection|
I think I understand your issue.
From the garbage collector's perspective, there is just a single list of all objects. When making passes, it just starts with known roots and propagates out, until over time, it's touched all live objects. I don't think somehow finalizing the gmMachine's global table is going to help.
What you may need is explicit destruction of your known resources, which you could control.
I haven't looked at how you've implemented custom gmUserObjects to see how straight forward it would be in your situation.
If I recall correctly, here's a couple of things myself and others have done:
1) Instead of storing a C++ ptr or resource directly inside a gmUserObject, store a handle or smart reference which can be nullified.
That way, in script, the gmObject can be alive but C++ object logically dead. This allows the application to control the lifetime of the native object and its dependent resources rather than the gmMachine.
2) When creating gmObjects that represent C++ objects, have C++ own them as a GC root.
On creation, call machine->AddCPPOwnedGMObject(m_userObject); // C Own gmObject
On Nullify, call machine->RemoveCPPOwnedGMObject(m_userObject); // C disown gmObject
If you didn't do something like this, you'd need to store a reference to all C++ owned objects in the global table, or such, just to keep them alive.
Related to (2), there is a templated helper called gmGCRoot<> which can help Add/Remove CPP owned objects.
I recall on shutdown, the code order must be:
gmGCRootManager::Get()->DestroyMachine(m_machine); // For gmGCRoot, call before destructing gmMachine
gmGCRootManager::Destroy(); // For gmGCRoot
I'm trying to recall and describe ways to make use of gmObjects which may finalize (called Destruct in the docs), in undefined order, while allowing the application to control the lifetime of native resources.
Let me know if I'm making any sense. I'm not very current with script issues.
|Page 1 of 1||All times are UTC|
|Powered by phpBB® Forum Software © phpBB Group