Page 1 of 1

Memory Management

Posted: Mon May 19, 2003 1:30 pm
by McGruff
I wonder what strategies people use to minimise memory usage.

1.VARS
(a) Simple one is to use $result['key'], $_POST['key'], $GLOBALS['key'] etc rather than declaring $var=$result['key'] .. and so on. If I'm processing user input, I'll often just to over-write the original, ie something like $_POST['var'] = addslashes($_POST['var']); rather than $var = addslashes($_POST['var']); Another advantage of that is that it remains clear throughout the script where the var came from.

2.RESULT RESOURCES
(a) Trivial one is not to find any column names you don't need.

(b) I wonder if you think it's best always to use either mysql_fetch_row() or mysql_fetch_assoc() (if you want key names). My thinking is that mysql_fetch_array() creates an array twice the size of the other two.

(c) According to the manual, a garbage collector thingummy frees up results when they're no longer needed. Does this operate only at the end of the script? If so, might be good to mysql_free_result() after you've finished fetching. This might only produce a noticable gain with a very long script and a very big result - or maybe it's not really necessary at all.

3.OBJECTS
(a) I've always wondered if creating a class object uses a significant amount of extra memory compared to simply using the same bunch of functions on their own - assuming it is feasible to use the functions without wrapping them in a class.

(b) Once I have instantiated a class, and got whatever output I need from it, suppose I want to free up the memory it uses without waiting until the end of the script. If $class = new Class; would I just unset($class) or would that destroy a var without actually destroying the object? I would guess the former since there doesn't seem to be a free_object() fn analogous to mysql_free_result().

Again, it might not really matter unless the object is a big resource hog and it's a very long script.

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

Freeing up result resources or objects before waiting for the script to end might help to reduce peak memory load on a very busy site but, I guess, this isn't really going to be a problem on the vast majority of sites. I just want to be ready for the day when Yahoo comes knocking on my door.. :wink:

Posted: Mon May 19, 2003 3:23 pm
by Captain Proton
Doing $var = $_POST['var']; does not use anymore memory than using $_POST['var'] directly:

http://www.zend.com/zend/art/ref-count.php

Posted: Mon May 19, 2003 3:41 pm
by []InTeR[]
Captain Proton wrote:Doing $var = $_POST['var']; does not use anymore memory than using $_POST['var'] directly:

http://www.zend.com/zend/art/ref-count.php
I do not agree,
i think that $var = &$_POST['var']; does not use anymore memory.

But the alias must allso be registerd, every value that is used costs memory. One way or a other.

Posted: Mon May 19, 2003 6:38 pm
by McGruff
Captain Proton wrote:Doing $var = $_POST['var']; does not use anymore memory than using $_POST['var'] directly:

http://www.zend.com/zend/art/ref-count.php
Thanks for the link which, for reference says:
Almost no memory is consumed when assigning an existing variable to a new variable
Avoiding use of "copy" vars could save memory however.

As soon as you change the value of a copy $var, it gets de-linked from $_POST['var'] and you now have two variables taking up two chunks of memory - in practice many scripts would operate like that.

For example, it's more efficient to do this:

Code: Select all

<?php
$_POST['var'] = addslashes($_POST['var']);
?>
..rather than:

Code: Select all

<?php
$var = addslashes($_POST['var']);
?>
In the former case, you do not create a new variable & stored value.

Referencing would be another way to do it, as was pointed out above. It sounds like whatever memory is used to store the reference is negligible.

Code: Select all

<?php
$var = &$_POST['var'];
$var = addslashes($var);
?>

What about objects

Posted: Mon May 19, 2003 8:09 pm
by netcrash
I you all in the php world...

How can be made their destruction(of objects) , does unset() terminate their existence ?!

Will finalize like in java be applied to PHP ?!

I use mysql_fetch_object()
I prefer using because i believe it gives me more freedom to control the output of data .
While using arrays is nice . Objects makes obtaining the result from the database quite easy .

What do you think about this ?!
Is mysql_fetch_array() better ?!
:?: :wink:

Posted: Mon May 19, 2003 10:29 pm
by McGruff
I'd forgotten all about mysql_fetch_object() to get a db query. I odn't know how that would compare with the other fetch methods in terms of memory use.

I was hoping someone would let us know if unset() can destroy an object (or if that's something you need to bother about at all).

Could do with some expert input in this thread.. :)

Posted: Mon May 19, 2003 11:51 pm
by jason
Using unset() will destroy the object. It's like anything else, it destroys the variable. Since in PHP4, a object variable is treated like any other variable.

However, you shouldn't have to worry about unseting your objects. PHP does this for you at the end of the script. If you are worried about memory problems from using too many objects, unset isn't going to help you. You just have to redesign your system. Look into maybe using Fishhook(? is that the name, I am never sure) pattern, or something else similiar.

As far as mysql_fetch_assoc/array/row, they all eat up the same basic memory. _object a bit more because of the object creation. Really, I don't think it gives any more control then an array. At this point, it's just syntax.

PHP has something called copy on write

Code: Select all

<?php

// This requires almost no work.  If you don't change $foo, 
// don't worry
$foo = $bar;

// This works the same for functions
function method ( $var )
{
	if ( $var ) {
		// do something
	}
}

/*
Even if $var was really big, it still follows the copy on write
feature.  If you don't change it, don't worry.  Creating
references takes more time.
*/
$foo =& $bar;
// This is not as efficient as the above example

/*
As a minor note.  In PHP, you should ALWAYS pass your
objects my reference, unless you know what you are doing.
*/

?>
In PHP, desctructors don't exist. However, you do have callback functions. You can have a function called at the end of the script. This function can call various destructors in other classes. I have this working for a debug class. I throw debug data, and at the end of the execution, I write to the file, not during the execution.

PHP5 will have all these cool features.

netcrash: finalize like in java? PHP isn't Java, first off. Secondly, you can do OO programming in PHP now, so if their is a feature in Java you are looking for in PHP, ask yourself if this is a Java feature, or a real OO feature. PHP isn't being modelled after Java, rather, its incorporating OO features. OOP existed before Java.

Posted: Tue May 20, 2003 12:29 am
by McGruff
Thanks for your comments.
jason wrote: As far as mysql_fetch_assoc/array/row, they all eat up the same basic memory
So the numerical and textual keys returned with mysql_fetch_array point to the same value rather than creating an array twice as big as the single key mysql_fetch_assoc / mysql_fetch_row?

As for destroying objects (or freeing results) I maybe didn't explain myself very well. Suppose you have a relatively large object or result at the start of a script that takes on average 0.3s to execute and you can kill the item after 0.1s. That's 0.2s of reduced memory load. These are just ball park figures but at best I think the gain would be of the order of a tenth of a second or so: on a very busy site, that might be significant. For anything else, it probably doesn't matter.

Well that's what I thought anyway. Just thinking out loud really and trying to get a deeper understanding of php scripting.

I believe

Posted: Tue May 20, 2003 1:34 am
by netcrash
That what jason means with :
As far as mysql_fetch_assoc/array/row, they all eat up the same basic memory
Is that the size in memory does not change because the values are the same.
No matter how they are returned.
What changes is the way the data is treated ... In case of the data being returned has
an object that implies the use of a variavel that is a ordered group ( i don't know how to explain
, i do not know mutch about this so ) :? anyway i trye, and i use a lot of oop in my webpages.

But commenting on what you said
McGruff :
As for destroying objects (or freeing results) I maybe didn't explain myself very well. Suppose you have a relatively large object or result at the start of a script that takes on average 0.3s to execute and you can kill the item after 0.1s. That's 0.2s of reduced memory load.
In my opinion the best way to do this is to control you're database queries .
Making it show a few values but NOTICE it's the querie that need's control in that case,
placing all in an array and showing eatch one at a time won't do any good .

That's my opinion .

Posted: Fri May 23, 2003 8:27 am
by BDKR
McGruff wrote:Thanks for your comments.
As for destroying objects (or freeing results) I maybe didn't explain myself very well. Suppose you have a relatively large object or result at the start of a script that takes on average 0.3s to execute and you can kill the item after 0.1s. That's 0.2s of reduced memory load. These are just ball park figures but at best I think the gain would be of the order of a tenth of a second or so: on a very busy site, that might be significant. For anything else, it probably doesn't matter.
I suspect that the greater gain here would be in long running scripts. In other words, more general purpose applications as opposed to web pages. If you've written a PHP-GTK app, console based interactive script, or a daemon of some sort, then you really don't want these processes sucking up resources
in a devil may care manner. In this case, destroy an object that MAY not be
needing any longer. If you KNOW['/b] you're going to use it again, then it's most likely better to leave it around and avoid the overhead of instantiation.

Remember also that in as much as you may be freeing up memory, there are
operations at the system level that has to occur to facilitate this. Being that PHP isn't capable of starting threads to handle this, your app isn't going to do anything else until the unset operation is complete.

I would say that in most instances, you can get by without freeing memory in a web setting.

Cheers,
BDKR

Posted: Sun May 25, 2003 6:23 pm
by 9902468
It's allways good to free resources that you don't need anymore. Atleast in other languages. I don't know how php internally works, but I've got the idea that unsetting resources manually one by one is actually slower than letting php discard them after the script is done. This is the scenario in php's main playground: parsing web pages. (Meaning short, little memory consuming scripts.) However, if php is used to heavier programming (php-gtk as earlier mentioned etc.) then one really should free used resources. For average php programmer I don't see any reason to even think things like this. Wasn't php designed to do this for you?

Second opinion: (tm)
If you write programs where you must consider memory usage all the time you should really use Java.

-9902468

Posted: Sun May 25, 2003 7:26 pm
by McGruff
I've kind of changed my whole way of thinking recently after some discussion in the style thread. The consensus does seem to be that it's more important to write fluid, easy to read code with as much abstraction as possible which is easy to adapt to different projects. While that may theoretically be more "inefficient" - say if you define lots of little functions instead of one 80 line monster - a key point was made by llimllib that php is a high-level language and the most important resource to consider is probably the programmer's time.