-
Notifications
You must be signed in to change notification settings - Fork 23
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
Memory leak #48
Comments
I've created simple PoC to make verification easier. https://github.com/maciejfikus/pgasync-memory-leak-poc Just run it with Any ideas? |
@maciejfikus Thanks for providing this test script. I've taken a look at can see some problematic behavior, but have yet to find a real memory leak here. Perhaps anybody else can also take a look at share their findings? Here's the gist of what your example is doing with some comments added by me: for($i = 1; $i <= 30000; $i++) {
$client->query('SELECT 1')->subscribe(…);
}
sleep(30);
var_dump(memory());
Any other input? What else could be causing memory leaks here? |
@clue, I am aware that this code is as naive as it could possibly be, but it does the job. So far, your analysis is perfectly correct. We can actually skip Client class by using single Connection class directly, the issue will preserve. I agree that sleep function shouldn't be here, used it purely for a debugging purpose. On the other hand, usage of sleep() function is irrelevant to the problem.
It is true and it has its flaws. Regarding
Yup, commandQueue is cleared after all queries passes. Memory usage drops with each finished query, but reserved memory stay unchanged. Assuming that I didn't make any huge mistake while testing it, my only suspicion right that open streams somehow keep memory high. It may be due to the fact I've no idea about stream's inner working tho. Aside from the unknown cause, could you confirm that you noticed a memory leak in your variations of this program? |
I have not yet had a chance to look at this. I use this library pretty extensively in long-running processes and have not noticed any memory leaks. I will run the example @maciejfikus created when I get some time and report back. |
@maciejfikus In your example project, the queries are async. The loop does not start until after the var_dump. So what is happening is you are creating the 30,000 queries - which get buffered to fire off once the connections are up and running. Also, I don't think it was ever connecting to the database - that is another issue that would need to be fixed: reporting that the database connection failed. Here is what I used to run the queries and show the memory usage: $client = new PgAsync\Connection([
'host' => 'db',
'port' => 5432,
'user' => 'devuser',
'password' => 'devsecret',
'database' => 'devdb'
], \EventLoop\getLoop());
for($i = 1; $i <= 60000; $i++) {
$queries[] = $client->query('SELECT 1');
}
\Rx\Observable::fromArray($queries)
->mergeAll()
->subscribe(
fn($result) => 5,
fn(\Throwable $result) => printf("Error: %s\n", $result->getMessage()),
fn() => printf("Done.\n")
);
\Rx\Observable::interval(1000)
->do(fn ($i) => printf("%d: %s\n", $i, json_encode(memory())))
->take(30)
->subscribe(); When using the Let me know if this answers the question about memory leaks. Thanks for posting a great issue - makes it much easier to help. |
@mbonneau, thanks for taking a look. Indeed, my example wasn't too fortunate, I intended to keep it as simple as possible and make a few mistakes while building that example gist. I've updated my example https://github.com/maciejfikus/pgasync-memory-leak-poc/blob/master/public/index.php Now what we get is just a single connection, loop, var_dump on each success to make sure that it comes from DB and periodic var_dump of Here is my output
After few minutes memory output is still the same. Now take a look into
|
Hi,
I haven't been able to find the exact reason by now, however it seems that we've got a serious memory leak somewhere around.
While using this library together with ReactPHP webserver (using FrameworkX), each single query to DB takes some memory which GC can't free after all. FrameworkX is implementation detail here.
Steps to reproduce:
There is not even need to fetch and return data.
Does anyone have any idea where it comes from or how to prevent it, even temporarily?
The text was updated successfully, but these errors were encountered: