amphp / hpack

HPack - HTTP/2 header compression implementation in PHP.
https://amphp.org
MIT License
97 stars 10 forks source link

Memory leak when using HPackNghttp2 #15

Open xpader opened 1 year ago

xpader commented 1 year ago

In my server, Ubuntu 20.04 (amd64), php 8.0.29, when using http-client with HPackNgHttp2, php process memory will getting keep increase. But change to HPackNative, php process memory will be stable within a certain range.

But the noted is memory info from memory_get_usage() is normal, looks like memory is leaking out of php memory manager, this makes memory_get_usage() can not get real memory usage.

Is this a FFI bug? or amphp/hpack bug?

Some related links: https://github.com/php/php-src/issues/8433

kelunik commented 1 year ago

How can this reproduced? I tried running requests in a loop, but this doesn't seem to reproduce it. How large is the leak?

xpader commented 1 year ago

@kelunik It's keeping increase, until system memory is exhausted. When I use HPackNgHttp2, I have to restart my application after 3~4 days in my 16G memory server.

My code have some different, every user have a single HttpClient instance, not shared HttpClient instance.

Maybe you can try create new HttpClient and do some request in loop, this may reproduced.

xpader commented 1 week ago

Even in V3 version of amphp http-client 5.x, this problem is still exists, just create a http client, continuously send many requests concurrently, and watch opened fd in system by cat /proc/sys/fs/file-nr you will see opened fd keep rising.

xpader commented 1 week ago

It's a bit strange, I've strongly recommended enhanced detection and use of libnghttp2 before https://github.com/amphp/hpack/issues/12, but now I wish there is a way to turn off using libnghttp2 and use HPackNative instead.

I'm now change code https://github.com/amphp/hpack/blob/master/src/HPack.php#L19 to below to keep my service stable for a long time.

    public function __construct(int $tableSizeLimit = 4096)
    {
        //if (HPackNghttp2::isSupported()) {
        //    $this->implementation = new HPackNghttp2($tableSizeLimit);
        //} else {
            $this->implementation = new HPackNative($tableSizeLimit);
        //}
    }
kelunik commented 1 week ago

@xpader Do you have a full reproduction script for the increasing memory usage?