php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48046 memory does not free with unset?
Submitted: 2009-04-22 13:11 UTC Modified: 2009-04-23 11:49 UTC
From: nikitin at freshframes dot com Assigned:
Status: Not a bug Package: Performance problem
PHP Version: 5.2.9 OS: linux suse 10.3
Private report: No CVE-ID: None
 [2009-04-22 13:11 UTC] nikitin at freshframes dot com
Description:
------------
I have a script running on two servers working on exactly the same data.

First server is a debian system with php 5.2.8, where no problems with memory occur.

Second server is a suse 10.3 with php 5.2.9, where i get:
PHP Fatal error:  Allowed memory size of 2097152000 bytes exhausted (tried to allocate 82 bytes) in ...



Reproduce code:
---------------
The output of the memory usage compared for each server:

Here the 5.2.8 debian:



  19 -       simple (5) : AR1312-16 (16.23/16.49) <br />
  20 - configurable (5) : AR1312 <br />
  20 -       simple (0) : AR1331-04 (16.33/16.58) <br />
  21 -       simple (0) : AR1331-07 (16.36/16.62) <br />
  22 -       simple (0) : AR1331-09 (16.40/16.65) <br />


Here the 5.2.9 suse server:

  20 - configurable (5) : AR1312 <br />
  20 -       simple (0) : AR1331-04 (91.98/92.06) <br />
  21 -       simple (0) : AR1331-07 (94.03/94.32) <br />
  22 -       simple (0) : AR1331-09 (96.08/96.37) <br />
  23 - configurable (0) : AR1331 <br />
  23 -       simple (7) : AR1338-16 (99.20/99.28) <br />

-> memory in brackets (actual/peak)
-> seems that php 5.2.9 has bad memory management?




Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-04-22 13:51 UTC] crrodriguez at opensuse dot org
unset has never freed memory, memory is freed at script shutdown.
 [2009-04-22 13:54 UTC] scottmac@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

Memory is never freed back to the system until the request ends, PHP will however re-use the memory assuming that a block the right size can be found.
 [2009-04-22 14:41 UTC] boettcher at freshframes dot com
You need 250MB memory_limit to execute.
-----
This script uses ~200MB at the end of script and got a peak of ~200MB.
If you uncomment the unsets you'll have less memory (current) usage and a slight less memory peak

-----
<?php
ini_set( 'memory_limit', '1000M' );

$data = $array_1 = $array_2 = $array_3 = array();

for( $i = 0; $i < 10000; $i++ ) $array_1[] = rand( 3456, 987641234 ) . str_repeat( implode( '', range( 'a', 'z' ) ), rand( 70, 200 ));
$data = array_merge( $data, $array_1 );
#unset( $array_1 );

for( $i = 0; $i < 20000; $i++ ) $array_2[] = rand( 1232, 987641234 ) . str_repeat( implode( '', range( 'a', 'z' ) ), rand( 160, 250 ));
$data = array_merge( $data, $array_2 );
#unset( $array_2 );

for( $i = 0; $i < 30000; $i++ ) $array_3[] = rand( 1239, 987641234 ) . str_repeat( implode( '', range( 'a', 'z' ) ), rand( 40, 100 ));
$data = array_merge( $data, $array_3 );
#unset( $array_3 );

#unset( $data );

$memory_peak = round( memory_get_peak_usage( true ) / pow(1024, 2), 2 );
$memory = round( memory_get_usage( true ) / pow(1024, 2), 2 );

echo "\nW/O Unset\nCurrent REAL Usage: " . $memory . 'MB -- Peak: ' . $memory_peak . "MB\n\n";

?>

---
statistics of my server (debian 4.0) [4 tests]
--
W/O Unset
Current REAL Usage: 207.75MB -- Peak: 212.75MB
-
W/O Unset
Current REAL Usage: 208.25MB -- Peak: 213MB
-
W/O Unset
Current REAL Usage: 208MB -- Peak: 212.75MB
-
W/O Unset
Current REAL Usage: 208MB -- Peak: 212.75MB
--
and now with unset uncommented [4 tests]
--
With Unset
Current REAL Usage: 40.25MB -- Peak: 209.75MB
-
With Unset
Current REAL Usage: 40MB -- Peak: 209.75MB
-
With Unset
Current REAL Usage: 38.75MB -- Peak: 209.75MB
-
With Unset
Current REAL Usage: 37.75MB -- Peak: 209.75MB
 [2009-04-22 15:03 UTC] scottmac@php.net
When you pass in true to memory_get_usage() and memory_get_peak_usage() you get the memory allocated from the system not the memory allocated for the script.

If you remove the values of true from both of these you'll see you should get.

With Unset
Current REAL Usage: 0.12MB -- Peak: 198.01MB
 [2009-04-22 15:56 UTC] nikitin at freshframes dot com
this is the output of a magento-shop item import script.
it requires csv data and db usage, i am afraid i cannot break it into pieces right now. 

but i like to give some more support about the error i get:

- whether i use unset or not, php5.2.8 on debian works, php5.2.9 on suse not
- i have a private server with debian php5.2.9-0.dotdeb.1 where it works, too

the debug says:
debian: php has a memory usage increase of 0.03-0.1mb per loop
suse: php has a memory usage increase of 2-3mb per loop

debian was my testserver, and suse is what our customer has.
beside that, scripts and data are totally equal

there is a warning whenever i use suse php5.2.9:
PHP Warning:  Call-time pass-by-reference has been deprecated in ...

-> but this does not occur in php5.2.9-0.dotdeb.1

so probably a php configuration problem? i dont know...
 [2009-04-23 11:49 UTC] nikitin at freshframes dot com
well today the import on the suse system worked like a charm...

no idea why, i am not the admin of the system, dunno if it was updated or not, scripts haven't changed...

if i experience the problem again, i will let you know...
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 09:01:28 2024 UTC