I've been investigating a memory leak of a long-running HTTPS process as part of https://rt.cpan.org/Ticket/Display.html?id=124927. I suspect the issue is within IO::Socket::SSL. This is against version 2.056.
If I regularly poll HTTPS servers in a long-running process, then the memory grows linearly without bounds over time. Analysis with Devel::MAT has so far revealed this is unbounded growth of the
my %SSL_OBJECT;
hash in IO/Socket/SSL.pm.
By inserting some `print STDERR` statements in key places, it appears that every time the poll interval comes up, it finds that the old connection has been closed by the server, so it has to be destroyed and recreated. The line
sub stop_SSL
1430: delete ${*$self}{_SSL_object};
runs, deleting the _SSL_object key from the instance, so that in a moment later when the SSL socket object itself is destroyed, the line
sub DESTROY
2010 my $ssl = ${*$self}{_SSL_object} or return;
finds nothing of interest, so returns before it gets to
2011 delete $SSL_OBJECT{$ssl};
This causes an unbounded accumulation of keys in %SSL_OBJECT, and so the process memory grows indefinitely.
Another small observation is that this seems very related to connection setup/close, because if I poll at sufficiently small interval (say, 1 second) then the servers I connect to don't get bored and timeout the connections, so sockets get reused. In that case, no new SSL connections need creating and old ones destroying, and the memory usage remains flat.
--
Paul Evans

> Thanks for debugging the issue. I've tried to fix the issue in
> https://github.com/noxxi/p5-io-socket-
> ssl/commit/7a19aaaf31cca0973179f820b81a3589fcacfe19. It seems to fix
> the problem for me. Please check if it fixes the problem for you to
> and if it does I'll release a new version.

Yeah, that patch appears to fix it for me too, my test script no longer leaks at either 1 or 10-second intervals.
Seems like a new version would be good then.
--
Paul Evans

Actually this doesn't quite seem resolved after all :(
With new version 2.058 we don't get any leaking ARRAYs any more, but we still have some leaking SCALARs.
I've traced that down with similar techniques, this time to the contents of the
%CREATED_IN_THIS_THREAD
hash. The connect_SSL or accept_SSL methods put keys into this hash, but (at least in my test-case with stop_SSL) the DESTROY method never gets a chance to remove them from the hash [line 2020] because $ssl isn't defined, having been deleted itself by stop_SSL [line 1437].
I don't quite see such a simple solution as before. Maybe moving more of the logic from DESTROY into stop_SSL might be best, and having DESTROY simply call it?
The attached patch does *seem* to fix the issue, but I'm not sure if it's making the underlying problem worse or not.
--
Paul Evans