ethrbunny has asked for the wisdom of the Perl Monks concerning the following question:

I have a SOAP server running inside a Win32 Daemon. The functions are served over HTTPS. Im finding that calling only the 'new' function in my module (via SOAP) is resulting in a memory loss (as observed by watching the win32 task list).
Here's my SOAP 'wrapper':
my $hHTTP; my $hDaemon = HTTP::Daemon::SSL->new(LocalPort => 8001, SSL_key_file => $curDir . "/certs/server-key.pem", SSL_cert_file => $curDir . "/certs/server-cert.pem" ) || die "Can't start SSH Daemon. $!\n"; my $soap = SOAP::Transport::HTTP::Server -> new ( ) -> dispatch_to(qw(auth)); while ($hHTTP = $hDaemon->accept) { while (my $request = $hHTTP->get_request) { my $req = $request->{_headers}{soapaction}; $soap->request($request); $soap->handle(); my $response = $soap->response(); $hHTTP->send_response($response); } $hHTTP->close(); }
In my test app I call the function as follows:
use SOAP::Lite +autodispatch => proxy => 'https://testbed.org:8001/', on_fault => \&handle_fault; my $obj = auth->new();
I've wrapped this file in a test.pl that exec's it, waits 3 seconds and repeats. Here's the 'new' function that gets called inside the SOAP service:
sub new { my $pkg = shift; my $self = {}; bless ($self, $pkg); return $self; }
All I can figure (at this point) (based on my limited understanding of Perl) is that SOAP or HTTP are keeping the pointers to the instances of my class and not letting them go. Im wondering if there is some way to coax the refcount of my package so it can be freed / GC'd.

Replies are listed 'Best First'.
Re: Leaking memory from SOAP service
by ethrbunny (Monk) on Jan 16, 2008 at 14:44 UTC
    FWIW: I fixed this by adding an 'undef' at the end of the HTTP loop. It looks like this now:
    while ($hHTTP = $hDaemon->accept) { while (my $request = $hHTTP->get_request) { my $req = $request->{_headers}{soapaction}; $soap->request($request); $soap->handle(); my $response = $soap->response(); $hHTTP->send_response($response); } $hHTTP->close(); ###### new line here ###### undef( $hHTTP ); }
      My mistake - this isn't really fixed. I don't leak memory if I only call 'new' but the problem continues if I call any other function.
      I added some 'Devel::Peek' code to my internal package and pulled it out of the Win32::Daemon in order to simplify the problem. Now Im finding that doing a 'Dump' of my 'this' pointer shows some reference counting that I don't understand but certainly looks to be leaking memory. Here is a simple case:
      HTTP / SOAP wrapper:
      sub http_thread { my $hDaemon = HTTP::Daemon::SSL->new(LocalPort => 8001, SSL_key_file => $curDir . "/certs/server-key.pem", SSL_cert_file => $curDir . "/certs/server-cert.pem" ) || die "Can't start SSH Daemon. $!\n"; my $soap = SOAP::Transport::HTTP::Server -> new ( ) -> dispatch_to(qw(auth)); while (my $hHTTP = $hDaemon->accept) { while (my $request = $hHTTP->get_request) { my $req = $request->{_headers}{soapaction}; $soap->request($request); $soap->handle(); my $response = $soap->response(); $hHTTP->send_response($response); } $hHTTP->close(); undef( $hHTTP ); } }
      This gets started via:
      $hThread = threads->create( {'void' => 1}, \&http_thread );
      The 'auth' class (my SOAP functions):
      package auth; use Devel::Peek; sub new { my $pkg = shift; my $self = {}; bless ($self, $pkg); my $cur_time = time; $auth_sessions { $cur_time } = 0; $self->{ SESSIONID } = $cur_time; Dump $self; return $self; } sub temp { my $self = shift; print "\n\n\ntemp\n"; Dump ($self); }
      I call the SOAP function as follows:
      use SOAP::Lite +autodispatch => proxy => 'https://server:8001/'; my $obj = auth->new(); use Devel::Peek(); print Dump($obj); $obj->temp(); exit;
      What I find is that in 'new' the refcnt = 1. When 'new' returns to my calling code refcnt = 4. When I call 'temp' and look at the SOAP pointer refcnt = 5.
      So the big questions are:
      1 - why is the reference count going so high?
      2 - how do I get it back down so that it will GC properly?

      EDIT:It appears to be a known problem: Link