20,741
edits
m (→Problem) |
|||
Line 479: | Line 479: | ||
naNew() is really just a fancy malloc() replacement, i.e. it's just getting passed the Nasal execution context, and the nasal type (which is mapped to the size of the requested memory region using naTypeSize()). | naNew() is really just a fancy malloc() replacement, i.e. it's just getting passed the Nasal execution context, and the nasal type (which is mapped to the size of the requested memory region using naTypeSize()). | ||
{{FGCquote|1= New nasal objects are added to a temporary bin when they are created, because further allocation might cause a garbage collection to happen before the code that created the object can store a reference to it where the garbage collector can find it. For performance and simplicity, this list is stored per-context. When the context next executes code, it clears this list. Here's the problem: we do a lot of our naNewXX() calls in FlightGear using the old "global context" object that is created at startup. But this context is no longer used to execute scripts* at runtime, so as Csaba discovered, it's temporaries are never flushed. That essentially causes a resource leak: those allocations (mostly listener nodes) will never be freed. And all the extra "reachable" Nasal data floating around causes the garbage collector to take longer and longer to do a full collection as time goes on, causing "stutter". And scripts that use listeners extensively (the cmdarg() they use was one of the affected allocations) will see the problem more seriously.|2= {{cite web | url = http://sourceforge.net/p/flightgear/mailman/message/15645369/ | title = <nowiki>[Flightgear-devel] Stutter/Nasal issue resolved (was: FlightGear/Plib periodic stutter notes)</nowiki> | author = <nowiki>Andy Ross</nowiki> | date = Oct 24th, 2007 }}}} | |||
{{FGCquote|1= Once listeners were added, scripts could be recursive: (script A sets property X which causes listener L to fire and cause script B to run) We need two or more contexts on the stack to handle that; a single global one won't work. I didn't like the fix though. Exposing the temporary bin as part of the Nasal public API is ugly; it's an internal design feature, not something users should tune. Instead, I just hacked at the FlightGear code to reinitialie this context every frame, thus cleaning it up. A "proper" fix would be to remove the global context entirely, but that would touch a bunch of code.|2= {{cite web | url = http://sourceforge.net/p/flightgear/mailman/message/15645369/ | title = <nowiki>[Flightgear-devel] Stutter/Nasal issue resolved (was: FlightGear/Plib periodic stutter notes)</nowiki> | author = <nowiki>Andy Ross</nowiki> | date = Oct 24th, 2007 }}}} | |||
The naNew() function is also implemented in misc.c, see [https://gitorious.org/fg/simgear/blobs/next/simgear/nasal/misc.c#line122 line 66]: | The naNew() function is also implemented in misc.c, see [https://gitorious.org/fg/simgear/blobs/next/simgear/nasal/misc.c#line122 line 66]: |