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
Tim Bunce
August 6, 2008 04:13
Re: [perl #56908] DBI memory leak in 5.10.0 due to change 26530
Message ID:
On Tue, Aug 05, 2008 at 10:00:12PM +0200, Bram wrote:
> Citeren " (via RT)" <>:
>> # <URL: >
>> 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)
> 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);
    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);

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.


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About