This is a discussion on PHP memory management within the PHP Language forums, part of the PHP Programming Forums category; Hi, I'm new to PHP programming (coming from C++); and all is well, except when it comes to memory ...
|
|||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
Hi,
I'm new to PHP programming (coming from C++); and all is well, except when it comes to memory management. Particularly, with passing objects/arrays in and out of functions. I've had so many unexpected results because of this feature, that I'm almost pissed off, almost. Things like, I have a class, with some callbacks (which default to functions inside the class). But when the default functions were called, $this couldn't see the values of the member variables. I found that my calling array($this, "fun") (for use in a call to call_user_func) was creating a copy of $this and thus it was a copy of the variables. Fixed with a $cb = array(); $cb[0] = &$this; etc... Later, with more problems, I found that $x = new y; made two copies (I've assumed from the testing I'd done). One where it calls the constructor, and then one when it copies it into $x. Fixed with a $x = &new y; (I consider myself lucky to have discovered this as it could very easily have gone unnoticed, had I not been setting up a reference to this in the constructor) Which makes me worry that there are other places I don't know about! ....and lots more of course... I guess with a little more care, it will be obvious where a problem exists, but as I am a newbie, I know it will continue to destroy me. Are there any tools or memory management functions that will allow me to see exactly how many copies of various objects/classes/strings I have. Or a way to dump a memory allocation when it happens or anything. I'm fearful that there may be millions of copies of my classes and such that I won't know about until it gets released - and two users go to the web site at the same time and cause the server to run out of memory. C++ is so much easier, I know exactly what memory is allocated, when and where, and when it will be destroyed. Whoever invented garbage collection and all that; a can of comeuppance upon them (not the good kind). Please, any information will be great. Thank you MRe |
|
|||
|
MRe <m.r.e.@.d.u.b.l.i.n...i.e> wrote:
> Things like, I have a class, with some callbacks (which default to functions > inside the class). But when the default functions were called, $this > couldn't see the values of the member variables. I found that my calling > array($this, "fun") (for use in a call to call_user_func) was creating a > copy of $this and thus it was a copy of the variables. Fixed with a $cb = > array(); $cb[0] = &$this; etc... I'm curious for your code... Care to show an example of what causes your trouble? [request for memorydebuggers] > Are there any tools or memory management functions that will allow me to see > exactly how many copies of various objects/classes/strings I have. Or a way > to dump a memory allocation when it happens or anything. I'm fearful that > there may be millions of copies of my classes and such that I won't know > about until it gets released - and two users go to the web site at the same > time and cause the server to run out of memory. Ehhh, you do know that all memory used by the script is (supposed to be) released when the script ends? -- Daniel Tryba |
|
|||
|
Hi, thank you for the reply,
One thing I forgot to mention, it's PHP 4, Apache (errm, version ?), on Linux > I'm curious for your code... Care to show an example of what causes your > trouble? One example coming up (hopefully a good one), it didn't go down too well... (please note, I had to copy this code _by hand_ from test code I wrote on the ol' laptop. If there are any compile errors in here, sorry, it is compile error free on the laptop. I guess I could have copied the code across on a floppy, but the floppy drive is on the other side of the room, I'd have to stand up!) class fun { var $callbacks; var $test; function fun() { $this->test = 1; $this->callbacks = array(); array_push($this->callbacks, array($this, "fun1")); $this->test = 5; } function test() { call_user_func($this->callbacks[0]); } function fun1() { echo($this->test."\n"); } } $fun = new fun; $fun->test(); ....I had expected this to output 5, but it output 1 (I assume it copied the class at... array($this ...before executing... $this->test = 5. ....Fixed with... $callback = array(); $callback[0] = &$this; $callback[1] = "fun1"; array_push($this->callbacks, $callback); ....And it works (outputting 5), further testing had me modifying the test function like this... function test() { $this->test = 10; call_user_func($this->callbacks[0]); } ....and lo and behold, it outputs 5, the bastard! I tracked this down to the... new ...call, which changing to... $fun = &new fun; ....fixes the problem (outputs 10) (I assume it created one instance of the class, called the constructor, returned, copying it, from new, and stored the copy in $fun, and as such, when... call_user_func($this->callbacks[0]); ....is executed, the class referred to by... callbacks[0] ...is the original copy (not the copied copy which had the... $this->test = 10; ...executed in it); is any of this making any sence) > Ehhh, you do know that all memory used by the script is (supposed to be) > released when the script ends? Whether I know that or not, I do now. But still, I don't like being at the mercy of the language; it thinks just because it cleans up after itself, that it's allowed to create as much clutter as it wants, copying arrays and objects and the likes every-which-way. I would be turning in my grave, if only I were dead. All I want to know is that when I access an object, that it's the one I created, and not a copy of an imitation. As they say, 'A mere copier of $this can never produce anything great' Thanks again, MRe |
|
|||
|
MRe <m.r.e.@.d.u.b.l.i.n...i.e> wrote:
[the example] Okay, getting a better view of what you are doing. [how you solved the problems] >> Ehhh, you do know that all memory used by the script is (supposed to be) >> released when the script ends? > > Whether I know that or not, I do now. But still, I don't like being at the > mercy of the language; it thinks just because it cleans up after itself, > that it's allowed to create as much clutter as it wants, copying arrays and > objects and the likes every-which-way. I would be turning in my grave, if > only I were dead. With any language you are at mercy of the specs. Specs for PHP(4) say, everything is passed by value (unless you tell is otherwise). But you found that out already :) You could have saved yourself a lot of frustration if you had found this url: http://www.php.net/manual/en/language.references.php > All I want to know is that when I access an object, that it's the one I > created, and not a copy of an imitation. As they say, 'A mere copier of > $this can never produce anything great' :) -- Daniel Tryba |
|
|||
|
Daniel Tryba wrote:
> You could have saved yourself a lot of frustration if you had found > this url: http://www.php.net/manual/en/language.references.php Even better, use PHP5 if possible. With the C++ background, and especially if you had some experience with Java, you'll feel right at home. Berislav -- If the Internet is a Marx Brothers movie, and Web, e-mail, and IRC are Groucho, Chico, and Harpo, then Usenet is Zeppo. |
|
|||
|
Hi again,
> > But still, I don't like being at the mercy of the language... > > With any language you are at mercy of the specs. Specs for PHP(4) say, > everything is passed by value (unless you tell is otherwise). But you > found that out already :) I'm diggin' that freaky groove - <sigh> > You could have saved yourself a lot of frustration if you had found this > url: http://www.php.net/manual/en/language.references.php A lot of good information there; good, intricate information. My tiny-little-mind is already on its way towards the TV. Lots of situations that create copies, that I would never have thought of, never (that second never is so I don't end on a preposition). I guess I'm just going to have to be super careful every time I do anything with objects, quit my whining, and eventually it should become second nature to me (the part about dealing with objects, not quitting the whining), right? Thank you again [very much] for your help. .... Just while I'm here, one thing I read at 'http://www.php.net/manual/en/language.references.whatdo.php' -snip php.net-------------------- *Warning* Complex arrays are sometimes rather copied than referenced. Thus following example will not work as expected. Example 19-3. References with complex arrays <?php $top = array( 'A' => array(), 'B' => array( 'B_b' => array(), ), ); $top['A']['parent'] = &$top; $top['B']['parent'] = &$top; $top['B']['B_b']['data'] = 'test'; print_r($top['A']['parent']['B']['B_b']); // array() ?> -end snip php.net----------------- What does, 'Complex arrays are sometimes rather copied than referenced', mean? Particularly the use of the word, 'sometimes'? When? The suspense! Or is the example the only case? Also, I don't understand the example. Where/why does the copy actually take place? I'm trying to trace what might be hippin'n-a'happenin' by following it in my mind, (along with a little debugging the code), but I don't get it! Little more help, please? Thank you, MRe. |
|
|||
|
Hi, thank you for your reply.
> Even better, use PHP5 if possible. With the C++ background, and especially > if you had some experience with Java, you'll feel right at home. Unfortunately, I don't have control over that - but it did get me thinking (unfortunately). Is PHP5 significantly different to 4 - that is, if someone were to switch from 4 to 5, would code break? Thank you for the help, MRe. |
|
|||
|
"MRe" <m.r.e.@.d.u.b.l.i.n...i.e> wrote in message
news:BbPZc.26436$Z14.8246@news.indigo.ie... > Are there any tools or memory management functions that will allow me to see > exactly how many copies of various objects/classes/strings I have. Or a way > to dump a memory allocation when it happens or anything. I'm fearful that > there may be millions of copies of my classes and such that I won't know > about until it gets released - and two users go to the web site at the same > time and cause the server to run out of memory. PHP uses techniques like reference counting and copy-on-write to manage memory. When copies of an object are made, PHP doesn't physically copy the contents. It just increments the reference counter of that object. So pass-by-value and return-by-value is not as expensive as you think. When a variable goes out of scope, the reference counter of the object it points to is decremented. When the counter reaches zero, the memory is freed (in theory). Physical copies of objects are made only when you make changes to one of the variables. In general, use references only when you need to. Creating references has more overhead and sometimes confuses PHP's garbage collection mechanism--e.g. when you have two objects referring to each other. > C++ is so much easier, I know exactly what memory is allocated, when and > where, and when it will be destroyed. Whoever invented garbage collection > and all that; a can of comeuppance upon them (not the good kind). PHP is a high level language. You really can't code in the same way as you do in C++. It would be like trying to make a pizza from scratch from a microwave pizza: "I can't toss this thing! And the salami is sticking to my rolling pin!" -- Obey the Clown - http://www.conradish.net/bobo/ |
![]() |
| Thread Tools | |
| Display Modes | |
|
|