Subject: | JavaScript leaks memory like a sieve |
When you run this script, even though both JavaScript and Perl have
discarded the "ThisObjectWillLeak" objects, they get left around in the
perl interpreter side (don't know about the javascript interpreter
side). 10 of these sample objects isnt a big deal, but when you're
dealing with millions of objects / references that you just want to have
Go Away, it gets kind of scary...
Subject: | leaktest.pl |
#!perl
use strict;
use warnings;
use Devel::Leak::Object qw(GLOBAL_bless);
use JavaScript qw(:all);
{
package ThisObjectWillLeak;
sub new {
my($class, $num) = @_;
return bless { n => $num }, $class;
}
sub whoami {
my $self = shift;
return "Leaky object #$self->{n}";
}
}
{
package ThisObjectWillNotLeak;
sub new {
my($class, $num) = @_;
return bless { n => $num }, $class;
}
sub whoami {
my $self = shift;
return "Sealed object #$self->{n}";
}
}
our $rt = JavaScript::Runtime->new;
our $cx = JavaScript::Context->new($rt);
sub dont_leak_an_object {
my $sealed = ThisObjectWillNotLeak->new(shift);
$cx->bind_object(sealed => $sealed);
return;
}
sub leak_an_object {
my $leaky = ThisObjectWillLeak->new(shift);
return $leaky;
}
sub write {
my $msg = shift;
print "$msg\n";
}
foreach my $i ('ThisObjectWillLeak', 'ThisObjectWillNotLeak') {
$cx->bind_class(
name => $i,
constructor => sub {},
methods => { whoami => $i->can('whoami') },
flags => JS_CLASS_NO_INSTANCE,
package => $i
);
}
$cx->bind_function(leak_an_object => \&leak_an_object);
$cx->bind_function(dont_leak_an_object => \&dont_leak_an_object);
$cx->bind_function(write => \&write);
foreach my $i (1 .. 10) {
$cx->eval("leaky = leak_an_object($i)");
$cx->eval("dont_leak_an_object($i)");
$cx->eval("write(leaky.whoami())");
$cx->eval("write(sealed.whoami())");
}