Here is a transcript of a message that just landed in my Inbox via Tamarin-devel@mozilla.org
Tamarin has a hybrid storage manager; reference counting takes care of a lot of freeing, but there’s a regular garbage collector that will deal with cyclically referenced objects. Objects that can be reclaimed by reference counting are reclaimed relatively promptly; the rest may take a while. The back-up collector is driven by allocation volume, so as the program runs and allocates storage (and doesn’t free it via reference counting) then the collector moves forward to a point where it will have scanned the entire heap and will reclaim garbage.
The reference count increment you describe is legitimate; when you create a closure it captures (increments references on) all objects in its lexical scope, and in a regular class method ‘this’ is one of those objects. There are optimizations that Tamarin could be doing that it’s not currently doing, by not capturing objects that contains only names that are not referenced from the body of the function expression. In your artificial example that would have helped you out, but it’s less clear whether it would help you out in a real situation where the body of that function would not be empty but would probably be referencing something in the surrounding class instance (ie ‘this’).
(All this information provided to you with the proviso that I’m relatively ignorant about unloading in Flash
![]()
–lars
I’ll try to (quickly and incompletely) point out one of the implications of what Lars explains here. This affects any ActionScript3 program that runs in Tamarin (including swf’s in Flash Player).
Let’s take a look at this code:
class MyClass { public function myFunction():Function { var usedObject:Object = {}; var unusedObject:Object = {}; var myClosure = function():Object { usedObject.field = 100; return usedObject; } //... return myClosure; } } //Later on, we use the closure var inst:MyClass = new MyClass; var fn:Function = inst.myFunction(); var o:Object = fn();
Now, as we know, the function myClosure has access to all variables in it’s scope chain, including locals of myFunction and instance members of MyClass.
The question is, what happens with each of the variables when they are not needed anymore?
For example, we expect unusedObject to be garbage collected right away. Well, it turns out that this is not the case. As Lars Hansen explains here, all variables accessible by the closure are captured by the closure. So they don’t get deleted until the closure gets deleted. More than that, the instance of MyClass (the “this” object) is also captured (linked), although you can’t directly use the keword this inside myClosure (it would point to the global object).
Bottom line, careful with closures. While they provide great convenience in coding, they might come with serious performance penalty.
Let’s just hope this will come to reality in the near future: “There are optimizations that Tamarin could be doing that it’s not currently doing, by not capturing objects that contains only names that are not referenced from the body of the function [...]”
Thank you Lars for these details!



