Skip to content

Memory leak if try to write in close socket #93

@oleg1540

Description

@oleg1540

Example

Loop::run(function () {
    $uri = "tcp://127.0.0.1:1337";

    Loop::repeat(500, function () {
        echo 'Counters: '. Test::$constructInc . ' - ' . Test::$destructInc . PHP_EOL;
        echo 'Memory: ' . round(memory_get_usage() / 1024, 2) . ' KB' . PHP_EOL;
    });

    $server = Amp\Socket\Server::listen($uri);

    while ($socket = yield $server->accept()) {
        $obj = new Test($socket);
        yield $obj->run();
        unset($obj);
    }
});

class Test
{
    public static int $constructInc = 0;
    public static int $destructInc = 0;

    public string $content;

    public function __construct(private \Amp\Socket\ResourceSocket $socket)
    {
        $this->content = str_repeat('a', 2048);
        self::$constructInc++;
    }

    public function __destruct()
    {
        echo 'destruct' . PHP_EOL;
        self::$destructInc++;
    }

    public function run(): \Amp\Promise
    {
        return \Amp\call(function () {
            try {
                $this->socket->close();
                yield $this->socket->write('test');
            } catch (Throwable $e) {
                echo 'catch exception' . PHP_EOL;
            }
        });
    }
}

Run script and try to connect by telnet several times

telnet 127.0.0.1 1337

Result in console

Counters: 0 - 0
Memory: 1284.35 KB
catch exception
Counters: 1 - 0
Memory: 1488.39 KB
catch exception
Counters: 2 - 0
Memory: 1522.4 KB
catch exception
Counters: 3 - 0
Memory: 1556.41 KB
catch exception
Counters: 4 - 0
Memory: 1590.41 KB
catch exception
Counters: 5 - 0
Memory: 1624.42 KB
catch exception
Counters: 6 - 0
Memory: 1658.43 KB
catch exception
Counters: 7 - 0
Memory: 1692.44 KB
catch exception
Counters: 8 - 0
Memory: 1726.45 KB
catch exception
Counters: 9 - 0
Memory: 1760.45 KB
catch exception
Counters: 10 - 0
Memory: 1794.46 KB
catch exception
Counters: 11 - 0
Memory: 1828.47 KB
catch exception
Counters: 12 - 0
Memory: 1862.48 KB

Test instances only created but not destructed. Memory consumption increases

If change vendor\amphp\byte-stream\lib\ResourceOutputStream.php:177 from

return new Failure(new ClosedException("The stream is not writable"));

to

throw new ClosedException("The stream is not writable");

got these results

Counters: 0 - 0
Memory: 1284.35 KB
catch exception
destruct
Counters: 1 - 1
Memory: 1449.94 KB
catch exception
destruct
Counters: 2 - 2
Memory: 1449.94 KB
catch exception
destruct
Counters: 3 - 3
Memory: 1449.94 KB
catch exception
destruct
Counters: 4 - 4
Memory: 1449.94 KB
catch exception
destruct
Counters: 5 - 5
Memory: 1449.94 KB
catch exception
destruct
Counters: 6 - 6
Memory: 1449.94 KB
catch exception
destruct
Counters: 7 - 7
Memory: 1449.94 KB
catch exception
destruct
Counters: 8 - 8
Memory: 1449.94 KB
catch exception
destruct
Counters: 9 - 9
Memory: 1449.94 KB
catch exception
destruct
Counters: 10 - 10
Memory: 1449.94 KB

Instances destructed, memory is stable.

PHP 8.1, amp 2.6.2, amphp/socket 1.2.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions