php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80108 APACHE+PHP not releasing memory in certain conditions on Win10
Submitted: 2020-09-15 22:33 UTC Modified: 2020-09-16 20:20 UTC
Votes:9
Avg. Score:3.0 ± 1.8
Reproduced:5 of 9 (55.6%)
Same Version:3 (60.0%)
Same OS:5 (100.0%)
From: gilperon at gmail dot com Assigned:
Status: Re-Opened Package: *General Issues
PHP Version: 7.4.10 OS: *
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2020-09-15 22:33 UTC] gilperon at gmail dot com
Description:
------------
I am running latest APACHE (2.5.x) + PHP (7.x) on my Win10 computer which has 8GB of RAM. All configurations are default.

When I start my Apache and check Windows Task Manager it shows the two Apache processes are using about 5 to 6 MB of RAM. Great. 

Now I saved the code below on a test.php file and execute it using my browser like this http://localhost/test.php 

The contents of that file is pretty simple, just this:

<?php

set_time_limit(0); 
ini_set("memory_limit","-1");

$temp = str_repeat("ffkl2kfj\nflkdsjf \rflksdjfldskjLJFDSL djsk|fhgjk{}fkgkjfdk",10000000);
explode("|",$temp);

echo "ended";

?>

After executing the code above and waiting till it shows ended, one of my Apache processes shows 400MB of RAM being consumed (the other Apache process is with 5-6MB of RAM). If I execute that code again, Apache will consume 700MB. Then again, it will show 850MB and so on. That's the bug itself. I know how memory leak works, how memory management works, variable lifecycle, stacks... So I came up with the minimum code to show you this bug.

NOW what is impressive, if that if after you call a few times the file test.php on your browser, if you create another file named test2.php with the contents being only <?php echo "x"; ?>, and if you execute that same file using your browser, you will see Apache memory usage drops to exactly HALF! Now execute it again, Apache`s consumed RAM will drop again exactly by 50%... and so on. Keep doing this until it reaches 5-6MB and it will stop dropping.

What is going on? This is a big problem to me and the only "escape" is creating scheduled task to restart Apache every 12 hours. I need to fix this cause in this computer I run a small webservice to a few friends and every once in a while Apache reaches almost 100% of memory usage and I need to restart it manually, even this webservice receiving no more than 10 or 20 requests a day. For some reason, Apache is not completely cleaning its memory after each request.

I know I should be using a linux distro (like Centos 8.x that I run on a VPS) if I want to run a realiable LAMP stack, but this bug is still pretty weird.

I am pretty sure PHP is doing something weird on the background which is not cleaning cache or any memory assigned location.

Test script:
---------------
<?php

set_time_limit(0); 
ini_set("memory_limit","-1");

$temp = str_repeat("ffkl2kfj\nflkdsjf \rflksdjfldskjLJFDSL djsk|fhgjk{}fkgkjfdk",10000000);
explode("|",$temp);

echo "ended";

?>

Expected result:
----------------
Memory should be released as soon the request was finished.

Actual result:
--------------
Memory is not being cleaned.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-09-16 06:57 UTC] sjon@php.net
-Summary: Major bug on APACHE+PHP not releasing memory in certain conditions on Win10 +Summary: APACHE+PHP not releasing memory in certain conditions on Win10 -Operating System: WINDOWS 10 AND CENTOS 8 +Operating System: windows 10
 [2020-09-16 06:57 UTC] sjon@php.net
> I know how memory leak works, how memory management works, variable lifecycle, stacks... So I came up with the minimum code to show you this bug.
> I am pretty sure PHP is doing something weird on the background which is not cleaning cache or any memory assigned location.

that's pretty awesome, you have a reproducible issue and the knowledge to fix it! :) In case you haven't noticed yet, we are an open-source project and the full sourcecode can be found here: https://github.com/php/php-src/tree/php-7.4.10/sapi/apache2handler

If the votes are any indication, there are more people experiencing this issue; meaning you can help fix this issue for others as well.

We welcome your pull-request!
 [2020-09-16 09:37 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2020-09-16 09:37 UTC] cmb@php.net
This is expected behavior.  On request shutdown, the Zend memory
manager does not free all allocated chunks, but rather retains
some[1] to avoid the need to reallocate them possibly for the next
request.

That does not imply, that there are no real memory leaks in PHP,
but the given test script does not show any.

[1] <https://github.com/php/php-src/blob/php-7.4.10/Zend/zend_alloc.c#L2273>
 [2020-09-16 13:44 UTC] gilperon at gmail dot com
Wow, by the votes, some other people reported the same issue! Great, hope some responsible non-sarcastic voluntary of PHP project can fix this. As I said, I know how memory management/leak work, but I have 0 idea how PHP source code was implemented. It would take me months to study PHP code only to fix this bug, so yeah, better hope that some good responsible person, that already knows inner workings of PHP, decide to fix this, or at least take a close look instead of just saying "this is expected behaviour, deal with it".

@cmb@php.net this is not expected, mainly if you have a server that gets thousands of requests like this. It will trash the RAM in seconds.
 [2020-09-16 14:10 UTC] cmb@php.net
-Status: Not a bug +Status: Re-Opened -Assigned To: cmb +Assigned To:
 [2020-09-16 14:11 UTC] cmb@php.net
-Operating System: windows 10 +Operating System: *
 [2020-09-16 20:18 UTC] gilperon at gmail dot com
Someone told me at SO to use:

gc_enable();
gc_collect_cycles();

However, even after using it, no memory is released. So how do I force Zend to release the cache/memory?
 [2020-09-16 20:20 UTC] nikic@php.net
Try gc_mem_caches().
 [2020-09-16 23:59 UTC] gilperon at gmail dot com
@nikic I tried what you said and it WORKED PERFECTLY!!! Literally perfectly. Right after executing "gc_mem_caches" the RAM usage drops to the normal 5-6MB!

Pretty awesome! So I think I will have to throw `gc_mem_caches()` all over my codes so it does not trash the RAM! Maybe you know some way I can tell PHP to better optimize the RAM usage? Something like: "hey PHP, if your Zend cache is over 500MB, please clear it." ?
 [2020-09-17 00:19 UTC] gilperon at gmail dot com
@nikic@php.net It also would be nice if at least Zend was smart enough to clear the cache everytime a request is terminated/finished. Anyway I can force that?
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Tue Oct 27 18:01:23 2020 UTC