k911 / swoole-bundle

Symfony Swoole Bundle
MIT License
260 stars 46 forks source link

Reduce PHP/Symfony Memory leaks #30

Closed zmitic closed 4 years ago

zmitic commented 5 years ago

First, I have to say this is amazing bundle. I really love it, speed diff is really big and my next project will definitely use it.

I do however have an issue. When used under FPM, I get this:

image

73ms, 2MB consistent.

But under this bundle:

image

First request is 16MB but it keeps pilling. This is from blank Symfony project with just 1 route (default). Any idea what is happening?

The problem is that I used this bundle in a real project where memory was over 80MB and it was actually slower than FPM.


Another update:

I made HMR to work. Speed increase is really big, can't wait to put it live!

k911 commented 5 years ago

Hi @zmitic, I'm afraid there is not much we can do, because that indicates PHP code written in your application does not clean state properly after returning responses. PHP-FPM flushes memory at the end of request, while idea behind swoole or any other event-loop based application is to not flush memory at all. (That's garbage collector's job)

zmitic commented 5 years ago

Yes, I understand that part, I was even the guy who wanted Symfony to support long-running process (https://github.com/symfony/symfony/issues/23984). So I am very careful not to do any memoization and Symfony itself does the same.

The code I am testing is blank Symfony4 application with just 1 route. Do you have memory issues like I do? My guess is logging in dev; when I started this app in prod mode, memory usage doesn't change at all which is expected behavior.

zmitic commented 5 years ago

Btw; I know this is different question but can HMR work when I change other files than just PHP?

k911 commented 5 years ago
  1. I'll leave this issue opened, because I believe there could be potential memory leaks in this bundle in many places, but as you've responded that's more like symfony framework problem. In HMR there is a cache for file names, but it shouldn't allocate so much memory. Maybe you could debug whether your aplication in dev mode has enabled https://github.com/k911/swoole-bundle/blob/develop/src/Bridge/Symfony/HttpKernel/DebugHttpKernelRequestHandler.php this part of code. It should be enabled by default in dev mode, unless there is a bug, but then you can use https://github.com/k911/swoole-bundle/blob/develop/docs/configuration-reference.md and set swoole.http_server.services.debug_handler: true which should make it enabled then.

  2. Do you mean to restart swoole server whether there are detected changes in other files than php in for example src/* path?

zmitic commented 5 years ago

My config is pretty much the default:

swoole:
    http_server:
        port: 9501
        host: localhost
        running_mode: 'process'
        socket_type: tcp
        ssl_enabled: false
        trusted_hosts: localhost,127.0.0.1
        trusted_proxies:
            - '*'
            - 127.0.0.1/8
            - 192.168.2./16
        static:
            strategy: 'advanced'
            public_dir: '%kernel.project_dir%/public'
        hmr: 'inotify'
        services:
            debug_handler: true
            trust_all_proxies_handler: true
            cloudfront_proto_header_handler: true
            entity_manager_handler: true
        settings:
            worker_count: 1
            reactor_count: 1
            log_file: '%kernel.logs_dir%/swoole_%kernel.environment%.log'
            log_level: auto
            pid_file: '/var/run/swoole_http_server.pid'

HMR started to work when I switched from auto to inotify. I tried many other options, memory consumption is always the same.

Do you mean to restart swoole server whether there are detected changes in other files than php in for example src/* path?

Yes, like /templates so twig changes can be seen w/o manual restart. Maybe new config array for that so users who make OSS bundles from /vendors or some /src/lib folder have easier time.

k911 commented 5 years ago

@zmitic Yeah, that's possible I think, unless it requires symfony container dump, then it would be much more complicated. I do not have much time for this project, and there are plenty of things that could be done here, so if you feel like doing contribution with this feature, feel free to send PR :)

zmitic commented 5 years ago

Fair enough. As soon as I finish current project (~2 months), I will give this a try. I would really like to have max speed, if nothing else just for fun.

sunchuo commented 5 years ago

@zmitic

i call gc_mem_caches(); gc_collect_cycles(); in page and request it many times, the memory didnt grow. i think the growth useage of memory may cause by gc delay. and profilerbar seems to be wrong with display mem useage.

mem useage:

FPM: 10M SWOOLE:19M

Rastusik commented 4 years ago

@zmitic hi, I think that your memory leak occurs because you have enabled doctrine logging/profiling in the Symfony DEV environment with APP_DEBUG=1 ... I had the same issue. Either disable logging/profiling, or create a resetter for the doctrine loggers. I have tested this bundle (well, actually my own fork of it) and it has no memory leaks, the only leaks were in my application code