Front page | perl.qa |
Postings from August 2022
Re: Having memory leak issues with perl-c
Thread Previous
|
Thread Next
From:
Mark Murawski
Date:
August 3, 2022 23:58
Subject:
Re: Having memory leak issues with perl-c
Message ID:
08b0a3a7-41ac-290d-e58a-31faed1bb90a@intellasoft.net
On 7/27/22 13:20, demerphq wrote:
>
> A general rule of thumb however is that any item you create yourself
> which is not "owned by perl" by being attached to some data structure
> it exposes is your problem to deal with. So for instance this:
>
> FNsv = get_sv("main::_FN", GV_ADD);
>
> is getting you a local pointer to the structure representing
> $main::_FN which is a global var. Thus it is stored in the global
> stash, and thus Perl knows about it and will clean it up, you don't
> need to worry about its refcount unless you store it in something else
> that is refcount managed.
>
> On the other hand
>
> hv = newHV(); // create new hash
>
> is a pointer to a new HV structure which is not stored in any place
> that perl knows about. So if you dont arrange for it to be recount
> decremented it will leak. However you then did this:
>
> svFN = newRV_noinc((SV *) hv); // reference to the new hash
>
> this is creating a new reference to the hash. The combination of the
> two basically is equivalent to creating an anonymous hashref. The
> "noinc" is there because the hv starts off with a refcount of 1, and
> the new reference is the thing that will "own" that refcount. So at
> this point you no longer need to manage 'hv' provided you correctly
> manage svFN.
>
> You then do this:
>
> sv_setsv(FNsv, svFN);
>
> This results in the refcount of 'hv' being incremented, as there are
> now two RV's pointing at it. You need to free up the temporary, or
> even better, simply dont use it. You dont need it, you can simply turn
> FNsv into an RV, and then set its RV field appropriately, the leak
> will go away and the code will be more efficient.
>
> Another comment is regarding the hv_ksplit() which seems redundant.
> The initial number of buckets is 8, the new size up is 12 or 16.
> Setting it to 12 is likely just a waste. Either set it much larger, or
> dont use it at all.
>
> Yves
>
>
I'm still not getting something... if I want to fix the code-as-is and
do this:
FNsv = get_sv("main::_FN", GV_ADD);
if (!FNsv)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
errmsg("couldn't fetch $_FN")));
save_item(FNsv); /* local $_FN */
hv = newHV(); // create new hash
hv_store_string(hv, "name", cstr2sv(desc->proname));
svFN = newRV_noinc((SV *) hv); // reference to the new hash
sv_setsv(FNsv, svFN);
// dostuff
SvREFCNT_dec_current(svFN);
SvREFCNT_dec_current((SV *) hv);
You're saying that the sv_setsv(FNsv, svFN); creates a second ref...
so in theory I can unref it and then all else would be equal
but I get this:
WARNING: Attempt to free unreferenced scalar: SV 0x55d5b1cf6480, Perl
interpreter: 0x55d5b17226c0.
Also.. something I didn't follow was this:
"or even better, simply dont use it. You dont need it, you can simply
turn FNsv into an RV, and then set its RV field appropriately, the leak
will go away and the code will be more efficient. "
How do you turn an SV into an RV without creating this extra reference..
Aren't I doing this already, with:
svFN = newRV_noinc((SV *) hv);
Thanks.
Thread Previous
|
Thread Next