Michael Fair wrote on Thu, Jul 12 2001 (23:58:53 -0700):
> I may be dense but wouldn't this code allocate 
> a new Cyrus::IMAP::Admin object each pass through
> the loop and the reference to the new object be 
> stored in the same location as the reference to 
> the instance from the previous iteration?

yes, exactly. it creates a new Cyrus::IMAP::Admin
object every time it passes through the loop,
and stores a reference to that object in the
scalar "$client".

however, $client is a lexical variable ("my $client"),
so the object should have its reference count decremented
(= destroyed) after each pass of the loop. try this:

# ---
use Cyrus::IMAP::Admin;
for (;;) {
    my $obj = Cyrus::IMAP::Admin->new('localhost');
}
# ---

$obj will get "destroyed" after each loop, because
the lexical goes out of scope. the Perl
garbage collection will take care of it by
automatically calling the DESTROY() routine within
Cyrus::IMAP, which is expected to free all resources
allocated by new().

this is handled by the XS function imclient_DESTROY
in IMAP.xs, which in turn calls imclient_close(),
which in turn leaks memory. apply this:

--- lib/imclient.c.dist Fri Jul 13 02:11:58 2001
+++ lib/imclient.c      Fri Jul 13 02:35:19 2001
@@ -335,2 +335,4 @@
     /*    if (imclient->state) imclient->mech->free_state(imclient->state);*/
+    sasl_dispose(&(imclient->saslconn));
+    sasl_done();

and the perl code snippet above won't leak anymore.

however, try addingg authenticate() and watch it
leak again:

# ---
use Cyrus::IMAP::Admin;
for (;;) {
    my $obj = Cyrus::IMAP::Admin->new('localhost');
    $obj->authenticate( -mechanism  =>  "login",
        -service    =>  "imap",
        -user       =>  "foo",
        -password   =>  "bar");
}
# ---

this makes me think that there are more
memory leaks within imclient/Cyrus::IMAP, and
it has nothing to do with perl semantics.

> Wouldn't a better approach be to create a new object
> before the loop, then open/close the connection
> each time you passed through the loop?

no, because it won't help. memory allocated
by imclient (or Cyrus::IMAP) isn't being
properly freed.

cu,
-- 
Toni Andjelkovic
<[EMAIL PROTECTED]>

Reply via email to