From: Sebastian T. <seb...@gm...> - 2010-12-13 19:59:37
|
Hi, 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! 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. 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? Cheers Till |