develooper Front page | perl.perl5.porters | Postings from August 2008

Re: [perl #56908] DBI memory leak in 5.10.0 due to change 26530

Thread Previous | Thread Next
From:
Tim Bunce
Date:
August 6, 2008 04:13
Subject:
Re: [perl #56908] DBI memory leak in 5.10.0 due to change 26530
Message ID:
20080806111244.GC6672@timac.local
On Tue, Aug 05, 2008 at 10:00:12PM +0200, Bram wrote:
> Citeren "lav@yar.ru (via RT)" <perlbug-followup@perl.org>:
>
>> # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=56908 >
>>
>> Under perl-5.10.0 the following simple program leaks memory,
>> while under perl-5.8.8 it does not. DBI module version is the
>> same under both perl versions (1.605). The leak seems to be not
>> specific to DBD driver, as it also happens with mysql and
>> oracle drivers.
>>
>> use DBI;
>> my $dbh=DBI->connect('DBI:NullP:');
>> while(1) {
>> 	my $q=$dbh->prepare(q{select 1 from dual});
>> }
>
> I've done a binary search on it with these results: (with DBI-1.607)

> The output with blead is the same. (meaning: it hasn't changed since)
>
> http://public.activestate.com/cgi-bin/perlbrowse/p/26530
> Change 26530 by nicholas@nicholas-saigo on 2005/12/30 01:08:46
>
> 	RMAGIC on symbol tables is bad, m'kay.
> 	Allow hashes (and therefore all symbol tables) to store the
> 	backreference array in the hv_aux structure, and thereby undo the
> 	performance damage of 24966, which resulted in 60% of all hash lookups
> 	trying to mg_find tiehash magic.
>
> I'll leave it up to someone else to figure out if it's a bug in the CORE or 
> a bug in DBI...

Having looked at the patch, and felt my eyes glazing over, I'm going to
point the finger at Nick first :)

Nick, in case it helps... DBI uses weakrefs for only one thing.
Whenever a new handle is created the parent handle's ChildHandles
attribute (an array ref) gets a weak ref to the new child pushed onto it.
This is the code that does that (search for weak in DBI.xs):

    AV *av;
    /* add weakref to new (outer) handle into parents ChildHandles array */
    tmp_svp = hv_fetch((HV*)SvRV(parent), "ChildHandles", 12, 1);
    if (!SvROK(*tmp_svp)) {
        SV *ChildHandles_rvav = newRV_noinc((SV*)newAV());
        sv_setsv(*tmp_svp, ChildHandles_rvav);
        sv_free(ChildHandles_rvav);
    }
    av = (AV*)SvRV(*tmp_svp);
    av_push(av, (SV*)sv_rvweaken(newRV((SV*)SvRV(orv))));
    if (av_len(av) % 120 == 0) {
        /* time to do some housekeeping to remove dead handles */
        I32 i = av_len(av); /* 0 = 1 element */
        while (i-- >= 0) {
            SV *sv = av_shift(av);
            if (SvOK(sv))
                av_push(av, sv);
            else
                sv_free(sv);
        }
    }

Let me know if that's doing anything wrong, or sub-optimally.
(I can see a few cleanups but nothing fundamentally wrong.)

One thing that's unusual is that these are weakrefs to *tied* hashes.
Perhaps that's an odd case not handled by the patch.

Tim.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About