php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68392 foreach memory usage increase
Submitted: 2014-11-10 17:39 UTC Modified: 2014-11-12 17:43 UTC
Votes:1
Avg. Score:1.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: ryan dot brothers at gmail dot com Assigned:
Status: Not a bug Package: Performance problem
PHP Version: 5.6.2 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: ryan dot brothers at gmail dot com
New email:
PHP Version: OS:

 

 [2014-11-10 17:39 UTC] ryan dot brothers at gmail dot com
Description:
------------
In the below example, the foreach in the global scope doesn't use any extra memory, but the memory usage almost doubles from doing the foreach inside test_function.  Is there a reason that so much extra memory is used?  I was expecting it not to use any extra memory as the foreach is done using a reference for each array element.


Test script:
---------------
<?php
function test_function($rows)
{
	echo memory_get_usage(true)."\n";

	foreach ($rows as &$row)
	{

	}

	unset($row);

	echo memory_get_usage(true)."\n";
};

$rows = range(1, 10000);

echo memory_get_usage(true)."\n";

foreach ($rows as &$row)
{

}

unset($row);

echo memory_get_usage(true)."\n";

test_function($rows);


Expected result:
----------------
1835008
1835008
1835008
1835008


Actual result:
--------------
1835008
1835008
1835008
3407872


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-11-12 09:19 UTC] xczgamer at gmail dot com
PHP copies arrays when send to a function.
Hence yes, the memory almost doubles as the entire array gets copied.
If you change the following line:
function test_function($rows)

to:
function test_function(&$rows)

The memory usage will remain the same.
 [2014-11-12 12:28 UTC] ryan dot brothers at gmail dot com
Yes, that's true, but if you use my original script and remove the foreach line in test_function, then the memory usage remains the same too.  I thought PHP uses copy-on-write rules to avoid duplicating variables.  Does doing a foreach on a variable count as writing to it?

Note also that the memory usage is higher if you do:

foreach ($rows as &$row)

rather than:

foreach ($rows as $row)

I'm not sure why doing &$row uses more memory vs doing $row.
 [2014-11-12 17:43 UTC] rasmus@php.net
-Status: Open +Status: Not a bug
 [2014-11-12 17:43 UTC] rasmus@php.net
That's due to how it is implemented prior to PHP7. In PHP7 it is much smarter. You test code on 7:

2097152
2097152
2097152
2097152
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Mon Feb 24 21:01:26 2020 UTC