Skip to content

Memory allocated by stream_context_create not released when destroying stream_socket_server #10885

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lucasnetau opened this issue Mar 20, 2023 · 4 comments

Comments

@lucasnetau
Copy link
Contributor

Description

I have a long running PHP application that is creating stream_socket_server over time, the memory allocated by stream_context_create() is never released even after closing and destroying the stream_socket_server. A minimal reproduction is below (backlog is set to allocate more memory on each loop however even an empty array to stream_context_create shows this issue). Eventually the application will crash, this is more evident in memory constrained environments like container deployments.

I found an old PHP bugs report referencing this with stream_socket_client (https://bugs.php.net/bug.php?id=61371) inhibition for deleting the context was too broad and a really old one that says that stream_context_create() memory is never released https://bugs.php.net/bug.php?id=40257 but this is not documented.

Output from memprof shows the allocated memory from stream_context_create()

image

<?php

$m0 = memory_get_usage(true);
for ($i=0;$i<50000;++$i){
    $context = stream_context_create(['socket'=>['backlog'=>511]]);
    $server = @\stream_socket_server(
        'tcp://127.0.0.1:0',
        $errno,
        $errstr,
        \STREAM_SERVER_BIND | \STREAM_SERVER_LISTEN,
        $context,
    );
    fclose($server);
    unset($server);
    unset($context);
    unset($errno);
    unset($errstr);
}
$m1 = memory_get_usage(true);
echo ($m1-$m0)/1048576,' MB allocated',PHP_EOL;

$cycles = \gc_collect_cycles() + gc_collect_cycles();
echo 'Ran ', $cycles, ' GC Cycles', PHP_EOL;

Resulted in this output:

46.00390625 MB allocated
Ran 0 GC Cycles

But I expected this output instead:

0 MB allocated
Ran 0 GC Cycles

PHP Version

PHP 8.0.28 - PHP 8.2.4

Operating System

No response

@lucasnetau lucasnetau changed the title Memory allocated by stream_context_create not released Memory allocated by stream_context_create not released when destroying stream_socket_server Mar 20, 2023
@damianwadley
Copy link
Member

Eventually the application will crash,

Meaning you've seen this issue actually crash the application? Or are you saying that it would hypothetically if it continued?
Because sometimes PHP will hold onto memory longer than it needs to, and it may appear that memory is leaking when actually PHP is simply not letting go of it yet.

@lucasnetau
Copy link
Contributor Author

@damianwadley It crashes the application with PHP Fatal error: Allowed memory size.

You can see in the example in the original report that if you stick a ini_set('memory_limit','40M'); at the top, the script will crash after 40214 iterations on PHP8.0.28 (faster on 8.2 as it uses more memory per context).

@iluuu1994 iluuu1994 self-assigned this Mar 20, 2023
iluuu1994 added a commit to iluuu1994/php-src that referenced this issue Mar 20, 2023
iluuu1994 added a commit to iluuu1994/php-src that referenced this issue Mar 20, 2023
iluuu1994 added a commit to iluuu1994/php-src that referenced this issue Mar 20, 2023
iluuu1994 added a commit to iluuu1994/php-src that referenced this issue Mar 20, 2023
`php_stream_context_set` already increases the refcount.
iluuu1994 added a commit that referenced this issue Mar 20, 2023
* PHP-8.1:
  Fix GH-10885: Leaking stream_socket_server context
iluuu1994 added a commit that referenced this issue Mar 20, 2023
* PHP-8.2:
  Fix GH-10885: Leaking stream_socket_server context
@HeenaBansal2009
Copy link

@iluuu1994 , I was going through this issue and was curious to know if this is applicable to :PHP 7.
I understand PHP 7 is out of support. But I do also observed seen in memory usage.
Thanks !.

@lucasnetau
Copy link
Contributor Author

@HeenaBansal2009 , yes https://3v4l.org/XBaaP shows that it was observable all the way back to PHP5.2 and likely before (my testcase uses memory_get_usage() which didn't exists prior to that)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants
@iluuu1994 @lucasnetau @damianwadley @HeenaBansal2009 and others