Bug #53669 [Com]: PHP does not return memory to system
| From: | jeffwhiting at hotmail dot com | Date: | Tue, 19 Apr 2011 16:09:05 +0000 |
| Subject: | Bug #53669 [Com]: PHP does not return memory to system | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-160285@lists.php.net to get a copy of this message | ||
Edit report at http://bugs.php.net/bug.php?id=53669&edit=1
ID: 53669
Comment by: jeffwhiting at hotmail dot com
Reported by: jille at hexon dot cx
Summary: PHP does not return memory to system
Status: Wont fix
Type: Bug
Package: Scripting Engine problem
Operating System: Linux 2.6.29.2-smp
PHP Version: 5.3.4
Block user comment: N
Private report: N
New Comment:
Thanks, I looked into apache_child_terminate but it is only available
for apache 1 sapi module. The documentation is pretty unclear but I
found that out the hard way. If it was implemented for apache 2 it
would have made things a lot easier for me.
Previous Comments:
------------------------------------------------------------------------
[2011-04-18 20:53:00] rasmus@php.net
Yes, it is a significant performance hit, and you should have a look at
the
apache_child_terminate() function.
------------------------------------------------------------------------
[2011-04-18 20:43:35] jeffwhiting at hotmail dot com
Is allocating memory really that much of a performance hit? It seems
like allocating memory is pretty cheap. I could see a large performance
hit if you were defragmenting the heap. Also something like that would
be easily tunable via php.ini so users could choose if they wanted the
performance penalty.
We are currently working around the situation by using the following
prepend file. What it does is monitor's the memory usage and tells the
apache child to gracefully terminate after you get above a memory usage
threshold. Sorry jille it is only useful with the apache sapi.
Honestly it is a pretty ugly hack but it works...
<?php
function apacheMemoryUsage()
{
$result = 0;
exec('ps -orss -p ' . getmypid(), $output);
$result = trim($output[1]);
return $result / 1024;
}
$memUseMB = apacheMemoryUsage();
$maxMem = get_cfg_var("apache_memory_limit_mb");
if (!$maxMem)
$maxMem = 128;
//error_log(getmypid()."> apache memory monitor: ".
// "using $memUseMB MB of $maxMem MB.");
if ($memUseMB > $maxMem && function_exists('posix_kill'))
{
error_log(getmypid()."> apache memory monitor: ".
"$memUseMB MB > $maxMem MB. Sending graceful stop.");
// Terminate Apache 2 child process after request has been
// done by sending a SIGUSR1 POSIX signal (10) which
// is a graceful stop.
function killApacheChildOnExit()
{
error_log('posix_kill: '.getmypid());
posix_kill( getmypid(), 10 );
}
register_shutdown_function( 'killApacheChildOnExit' );
}
?>
------------------------------------------------------------------------
[2011-04-12 22:40:42] jille at hexon dot cx
I understand it won't be possible to free all of the used memory, mostly
due to
fragmentation. Our scripts use over 100MB of memory and I don't believe
every
page is used.
When looking at zend_alloc.c in _zend_mm_free_int: (5.3.6)
if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(mm_block, size))) {
zend_mm_del_segment(heap, (zend_mm_segment *) ((char *)mm_block -
ZEND_MM_AL
IGNED_SEGMENT_SIZE));
} else [...]
Shouldn't that free every segment no longer used? As segments are 2MB by
default, it could be possible there are some parts used in every
segment, but I
don't think that is very likely when running over hundreds of
megabytes.
If above isn't suppose to "fix my problem", would it be possible to
create a
function that checks whether it can remove any segments? That way the
performance hit can be controlled.
------------------------------------------------------------------------
[2011-04-12 22:17:07] rasmus@php.net
There are plenty random things that stay on the heap across requests.
Persistent
connections, the statcache and a number of other things, so it is pretty
much
impossible to do this in a heap-based allocator. For mmap stuff it would
be
technically possible, but again, the performance hit for doing so would
be pretty
nasty.
------------------------------------------------------------------------
[2011-04-12 21:42:10] jille at hexon dot cx
When looking at zend_alloc.c it seems to support several memory
allocators. As
far as I know when you munmap() pages they should be returned to the
system. Am I
looking in the wrong page and is the problem somewhere the munmap()?
We are using the CLI sapi instead of the Apache sapi as jeffwhiting
does.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/bug.php?id=53669
--
Edit this bug report at http://bugs.php.net/bug.php?id=53669&edit=1