From: Carsten N. <car...@gm...> - 2010-12-14 15:25:29
|
Hello, On 12/13/2010 01:59 PM, Sebastian Till wrote: > I finally found and understood the problem. The StatePtr, TextureChunkPtr, etc. > of the material classes are definitely causing my memory leaks. The following > explanation will just mention the StatePtr although other attributes of material > classes that aren't contained in an SField are affected, too. I will call these > attributes CachePtrs. > > When a material is created in thread A a StatePtr is created (indirectly by a > call of rebuildState/endEditCP), too. The call addRefCP on this StatePtr will > also put a "Refcount increased" entry to Thread A's changelist. So, after a > synchronisation with Thread B the StatePtr Refcount is 2. However, no instance > of Thread B will ever point to this StatePtr instance since it isn't contained > within an SField. Thread B will create an additional, independant StatePtr instance. > This means that if I destroy the material in Thread A: each aspect's material > destructor will call subRefCP on its own version of the StatePtr. So, aspect B's > StatePtr will decrease from 1 to 0 but aspect A's StatePtr just from 2 to 1! ok, but there should also be a "Refcount decreased" entry in A's Changelist, which on the next sync should take care of destroying A's State object. I'd like to understand why that does not happen/work in this case, since this is the mechanism that also takes care of the more usual cases. > I think that I found a "not that beautiful" way around this issue. My idea was > to disable the adding of "Refcount increased" entries to changelists for > CachePtrs. I've done that by adding three functions in addition to addRefCP, > subRefCP and setRefdCP to OpenSG. They got similar names: addCacheRefCP, > subCacheRefCP and setCacheRefdCP. They basically do the same as their siblings, > however, they set the current changelist to read only, do the things they have > to do and then reset the changelist's read write access. I now replaced all > calls of xxxRefCP with a StatePtr as a parameter (or a CachePtr) to calls of > xxxCacheRefCP. > > The State class itself needed some fixing, too. I've noticed that a state is > never synchronised between its aspects. Calls for addChunk or subChunk would > therefor raise similar memory leak problems since they also use the xxxRefCP > methods to increase or decrease the refcount. > Materials add their CachePtrs to their StatePtrs via State::addChunk. This > increases a CachePtrs refcount and it would again add an "refcount increased" > entry to the changelist. However, since the StatePtr aspects are never > synchronised, just one aspect's destructor would decrease the refcounts of its > chunks. So, I replaced all xxxRefCP calls with xxxCacheRefCP here, too. not putting the ref count changes into the changelist may be the right thing for State objects in Material, but if there are other places it is used the situation might be different. > My application doesn't create memory leaks anymore but I still wanted to discuss > my changes since they are ugly. Is there something I should be beware of now? hm, one thing that depends much more on the changelist than multiple threads on one machine is the cluster code, so there is a possibility it is broken with the changes. Cheers, Carsten |