Reputation: 19507
I'm interested in the possibility in memory(unneeded reference) leaks of memory leaks in garbage collected languages
caused by variables caught in closures which are stored (perhaps as part of an object system or as part of building actions based on input to be evaluated later).
Are there any languages where this sort of thing is somewhat common? If so what are the patterns to watch out for in those languages to prevent it?
Upvotes: 3
Views: 2948
Reputation: 81217
In many languages, if multiple delegates are created that close over some variables in a given scope, every delegate which closes over any of those variables will close over all of them. For example:
Action blah(Dictionary<string, int> dict, List<string> list)
{
int i;
list.ForEach( (st) => if (dict.Contains(st)) i++; );
return () => Console.WriteLine("The value was {0}", i);
}
That method will create two delegates. The first needs variables dict
and i
, and will be abandoned before the function exits. The second only needs i
but could be held indefinitely by the caller. As long as the caller keeps the delegate returned by this method, the passed-in dictionary will not be collectible.
It would be possible for a compiler to avoid this issue by generating two closures, one of which held a dict
and an int[1]
, and the other of which just held an int[1]
; both closures would hold a reference to the same int[1]
, thus preserving the required semantics. In practice, though, the extra costs associated with the excess captures.
Upvotes: 1
Reputation: 20493
It is not really what you mean, but the garbage collector in Internet Explorer < 7 used not to be able to collect variables with circular references. This has not much to do with closures per se, but it turns out closures in javascript can create circular references quite easily.
I think a pattern like this would do
function foo() {
var div = document.getElementById('mydiv');
div.onclick = bar;
function bar() {
div.style.opacity = 0.5;
}
}
Now, whatever you do, the function bar
references the variable div
, and at the same time is assigned to a property of div
.
As a consequence, it used to be necessary to put particular attention when using closures on IE to avoid memory leaks.
Upvotes: 1
Reputation: 48486
As long as the closure is referenced, the captured variables will be kept. As a result, you need to be careful about where you create references to those closures.
Event handlers that are not unsubscribed are a potential source of many types of leaks. However, I can't really think of any generic patterns that will help you in every conceivable way you may be using closures :)
Upvotes: 3
Reputation: 43094
Variables in a Closure are not 'caught' but are simply still referenced, the GC isn't going to collect them until the reference is released. When the application terminates then any outstanding Closures are going to de-reference and any associated resource released. No memory leak as all allocated resources are released.
Upvotes: 0