Discussions on Ref Counting and Regions (and whatever may replace them).
IRC 01/12/07
IRC 04/12/07
IRC 16/01/08
IRC 18/01/08
Problems with current regions and references held:
Work badly with shared resources,
Doesn't free resources correctly, in the majority of cases memory is 'semi-leaked' so memory usage becomes very high after lots of time spent moving between regions (over 700mb for PS after an hour play on average, instead of ~300mb).
Fairly bloated (holds a lot of references),
We have circular references, these should be avoided wherever possible imo (or use weak references for linking to a parent object).
A possible replacement system; Collections (or other name):
Goal: A lightweight system to group objects in such a way which makes it easy to correctly free them when no longer used.
It would be good to set some guarantees for this system, these are the two important ones I can think of right now:
1) Any object with a reference held by a collection will not be freed or removed from the engine lists before being released by the collection
2) Any object with a reference held by a collection or parent with a reference held by a collection will always be freed when no longer used.
A collection is created by the user whenever he wishes to store related data with the guarantees above. Two examples are; loading a map, storing textures and materials for effects.
This data is then loaded via current csparser functions with the option to either hold minimal references to objects or a reference to every object. The former might be used for the first example and the latter for the second.
When the user is finished with this collection of data he unloads it. The internal process of unloading the collection involves removing all references to child objects, calling a helper function to check all engine lists for objects which are now unused, then destroying itself.
This is all the collection should do, as basic functionality. It can be extended if more functionality is wanted, and functions can be made to use the engine's list of collections also.
These should be rather quick to implement, the hard part is making sure that everything is referenced correctly within the engine and that nothing is needlessly referenced.
General Ideas:
We need to keep the amount of references as low as possible, firstly because it improves performance and secondly because it reduces complexity.
I suggest that by default a collection holds a reference only to the 'top level' objects (sector?), and no references to other objects like textures.
So in a sense, there is a tree-like structure with the collection as the 'root'. When the collection is unloaded it releases its references to these top level objects and then runs helper functions which search the engine's lists for objects which can be released (only the engine holds the reference).
The Collection releases the refs on the sector, the sector is freed which releases the refs on the meshes, these release their refs on the materials etc. So the whole thing neatly collapses.
As mentioned above, there should be a non-default option to hold a reference to everything, which is useful in many situations.
res: It might be a good idea to *always* store things in a collection, either one specified by the user, or an implicit (or default) one - otherwise it gets awkward to define consistent semantics if "object is in some collection" vs "an object is not in some collection".
A) Well, I had kind of forced a choice in the user with the above, either they use collections for everything or they don't use them at all. If they don't use them at all then they have to handle all object unloading themselves. Having a default collection might be a good idea, which would mean that any objects stored in it won't be released until the program is closed or until the user manually removes them.
res: What about mesh factories? Are they not supposed to be stored by collections? If they are, you can't store only the sector b/c a mesh factory isn't attached to any.
A) Yes, we can define exactly which defaults to having a reference held and which don't. There's nothing wrong with having multiple 'top level' objects.
res: Please elaborate on "hold minimal references to objects" vs "a reference to every object".
A) Minimal is where you only hold references to objects which are marked to always have a reference held by a collection. A reference to every object means that every object which is loaded is put into the current collection (like is done today).
Draft Proposal of Changes and Additions
All objects will either have a reference held by a collection or a parent/grandparent etc. who has a reference held by a collection.
There will be a default collection to satisfy the above in the case that a collection isn't specified.
The engine lists will now only hold weak references to objects, and objects will be freed via ref counting by the engine.
The current unused resource helper functions will be deprecated along with Regions, and new ones will be added to give users who only use the default collection some control over unloading and to help in any other areas I can think of.
Things to think about:
All objects who fall in to the latter of the above (parent/grandparent reference held) will have a weak-reference to them held by the same collection which holds the parents/etc. reference. This is to speed up searching, but I'm unsure whether this is worth the cpu and memory overhead of all these weak refs.
