ID:               37929
 User updated by:  joe at estara dot com
 Reported By:      joe at estara dot com
 Status:           Open
 Bug Type:         Apache2 related
 Operating System: Linux
-PHP Version:      5.1.4
+PHP Version:      5.1.4, 4.4.0
 New Comment:

So I rewrote the unserialize function in php, and it still is
happening.   Totally bizare, the leak must be somewhere deeper in PHP. 
 If I make copies of the array using array_merge it doesn't use more
memory, but if I unserialize again it uses more memory each time, even
in an ALL php version.   Please email me if you want example data file.


Previous Comments:
------------------------------------------------------------------------

[2006-06-30 18:42:39] joe at estara dot com

This is not the operating systems fault. This is PHP's fault.  It's
present in 4.4.0-4 as well. Under debian and fedora core 4.   

This leaks 800M of ram on a single run.

<?php

ini_set("memory_limit", "800M");
for($i=0;$i<160; $i++) 
  $s[$i] = file_get_contents("ziplatlong"); 
for($i=0;$i<160; $i++) 
   preg_match("/foo/", $s[$i]);

This uses 800m but immediately returns it to the operating system under
both versions and OSs. 

<?php
ini_set("memory_limit", "800M");
for($i=0;$i<260; $i++)
  $s[$i] = file_get_contents("ziplatlong");
for($i=0;$i<260; $i++)
   preg_match("/foo/", $s[$i]);

I'll email you a zip file so you can easily reproduce this PHP bug.

------------------------------------------------------------------------

[2006-06-28 13:09:32] joe at estara dot com

Tony; 
Why then when I rewrite this to be exactly the same except for the
unserialize does it give all the ram back?   I've tried this with 6
different methods to grab a bunch of ram, every other method returns
the ram on exit.  unserialize is the only path with a memory leak.

------------------------------------------------------------------------

[2006-06-28 08:12:52] [EMAIL PROTECTED]

PHP releases all the memory taken during the request and it's up to the
memory manager used in your OS to decide when to start using it in other
processes.
Not PHP problem.

------------------------------------------------------------------------

[2006-06-27 14:44:56] joe at estara dot com

Description:
------------
If you use unserialize on a large multidimensional array, each apache
process it runs in ends up taking up over 68m of ram (the actual size
depends on your array that you're unserializing)   This is actual ram
(Resident minus shared ram), and doesn't return it to the operating
system after the script exits.  Since you have say MaxClients in
apache2 of 150, 150 times 68m of ram means swapping to death.  This is
using prefork.

Reproduce code:
---------------
<?php

ini_set("memory_limit", "64M");
# ziplatlong is an array, with zip code as a key and a 2 element lat
long array as the value
$s = file_get_contents("ziplatlong"); 
$zip = unserialize($s);
preg_match("/foo/", $zip["00601"][0]);


Expected result:
----------------
I'd expect most of the ram returned to the operating system.  When I do
something similar, use the same levels of ram, apache only takes up ~10M
of ram, even though it uses ~64M while processing.

<?php

ini_set("memory_limit", "64M");
for($i=0;$i<50; $i++) 
  $s[$i] = file_get_contents("ziplatlong"); 
preg_match("/foo/", $s[38]);


Actual result:
--------------
Machine swaps to death.


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=37929&edit=1

Reply via email to