Skip to content

Memory allocated by stream_context_create not released when destroying stream_socket_server #10885

Closed

Description

@lucasnetau

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

Activity

  1. changed the title [-]Memory allocated by stream_context_create not released[/-] [+]Memory allocated by stream_context_create not released when destroying stream_socket_server[/+] on Mar 20, 2023
  2. damianwadley commented on Mar 20, 2023

    @damianwadley
    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.

  3. lucasnetau commented on Mar 20, 2023

    @lucasnetau
    ContributorAuthor

    @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).

  4. self-assigned this
    on Mar 20, 2023
  5. added a commit that references this issue on Mar 20, 2023
    bf8f06f
  6. HeenaBansal2009 commented on Jul 3, 2023

    @HeenaBansal2009

    @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 !.

  7. lucasnetau commented on Jul 3, 2023

    @lucasnetau
    ContributorAuthor

    @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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions