[rt-devel] debug info on memory leaks under mod_perl.
Ruslan U. Zakirov
cubic at acronis.ru
Tue Oct 21 04:46:08 EDT 2003
Jesse Vincent wrote:
>
>
> On Mon, Oct 20, 2003 at 07:41:51PM +0400, Ruslan U. Zakirov wrote:
>
>> Hello, RT hackers :)
>> I want to remember to you that RT leaks.
>>
>> While my last hacking on RT I've understood that Perl and CPAN
>> modules could be buggy too and at first time complain on them. But after 13
>>hours of fighting with Apache::Leak, B::LexInfo, die 'Test',
>>Data::Dumper and other similar shit I figured out that it's almost only
>>RT problem.
>>
>> The problem is circular references.
>>Good article about it here:
>>http://www.perl.com/pub/a/2002/08/07/proxyobject.html
>>
>>We leak at least one CurrentUser object + all object on which it has
>>pointer(PrincipalObj, UserObj...) Why? Because of 'user' references on
>>CurrentUser which have each object inherited from RT::Handle and
>>RT::Record. And also CurrentObject itself have such pointer. So after
>>untie of %session perl never call DESTROY on this objects.
>>
>>1) weaken solution is good, but have issues
>> a) perl should be >5.6.0, but it's not a problem for RT. RT have
>> same requirments.
>
>
> The following change has been made to RT::Base:
>
> sub CurrentUser {
> my $self = shift;
>
> if (@_) {
> $self->{'user'} = shift;
> |+ Scalar::Util::weaken($self->{'user'}) if (ref($self->{'user'}) &&
> |+ $self->{'user'} == $self );
> }
>
>
> With this in place, RT passes all tests and the following test script
> shows that object destruction is taking place immediately:
>
Yep. This do Right thing, this is first what I do when was testing
'weaken' solution. But if we add one string?
> sh-2.05a# more memtest
> #!/usr/bin/perl
>
> use lib qw(/opt/rt3/lib);
> use RT;
> RT::LoadConfig();
> RT::Init();
>
> use RT::CurrentUser;
> sub RT::CurrentUser::DESTROY {
> print "HULK SMASH!\n";
> }
> for (my $i = 1; $i <= 500; $i++) {
> print "Loading user $user...";
> my $user = RT::CurrentUser->new('root');
my $UserObj = $user->UserObj;
>
> }
>
> print "Done";
>
Same with principal object. And bad thing is that we could not isolate
using of 'weaken' in CurrentUser class. If we do $self->{'UserObj'}
weaken then when RT lost somewhere pointer on it $self->{'UserObj'} it
would be undefined and calling it cause another select to DB. :(
More information about the Rt-devel
mailing list