Talk:Using transactions

13 Nov 2006

Edward Sabol: Please prove that closures referencing external variables will leak because I think what you say is misleading and I've got a test script below to test the theory. The only way closures leak memory afaik is when you assign a sub {} to a scalar and then let it call itself recursively as such: my $leaky; $leaky = sub { my $count = shift; if ($count > 0) { &$leaky($count - 1); } }; &$leaky(10);

See this test script (requires Devel::Leak):

use strict; use Devel::Leak; my $handle; my $count; my $new_count; print "Test 1 (circular refs). This will leak.\n"; $count = Devel::Leak::NoteSV($handle); print "\tPre count: $count\n"; &test_circ_refs; $new_count = Devel::Leak::NoteSV($handle); print "\tPost count: $new_count\n"; print "Test 2 (self-referencing closure). This will leak.\n"; $count = Devel::Leak::NoteSV($handle); print "\tPre count: $count\n"; &test_closure_self_ref(10); $new_count = Devel::Leak::NoteSV($handle); print "\tPost count: $new_count\n"; print "Test 3 (closure referencing external vars). This won't leak.\n"; $count = Devel::Leak::NoteSV($handle); print "\tPre count: $count\n"; &test_closure_ext_ref(10); $new_count = Devel::Leak::NoteSV($handle); print "\tPost count: $new_count\n"; sub test_circ_refs { my $a; my $b = \$a; $a = \$b; } sub test_closure_self_ref { my $count = shift; my $code; $code = sub { my $count = shift; print "\t\trecursion: $count\n"; if ($count > 0) { &$code($count - 1); } };  &$code($count); } sub test_closure_ext_ref { my $count = shift; while ($count > 0) { &{sub { my $foo = $count; $count--; print "\t\trecursion: $count\n"; }}; } }
 * 1) !/usr/local/bin/perl -w

-- cmanley

I suppose the only evidence I have handy at the moment is anecdotal, often experienced when using Error.pm's try/catch syntax in mod_perl applications. I will defer to your mad Devel::Leak skillz, however, and change the text accordingly to indicate that closures may occur.

-- EdwardSabol 17:52, 15 November 2006 (GMT)