You are here: references, circular references, oop, and garbage collection in PHP5 « PHP « IT news, forums, messages
references, circular references, oop, and garbage collection in PHP5

Posted by Alan Pinstein on 12/07/05 00:23

So.. I am having PHP5 memory management problems.

They are similar to those described in this thread:

http://aspn.activestate.com/ASPN/Mail/Message/php-Dev/1555640

(so maybe this question belongs on php-dev but I figured I'd try here
first... seems like a userland question)

Basically I have an object model to represent db objects, and I am
bulk-loading the objects via some PHP scripts. Sadly the scripts
consume unbounded memory because of this problem.

I have done a lot of programming in C++ and Obj-C and the normal way
to handle circular references is to have parents "retain" (keep ref-
counted links) to their kids, and have the kids have "weak
references" (non-ref-counted) links to their parents. This way, when
the parent is no longer used, it will automatically 0-out the ref
counts to all children it links too and things GC correctly.

Now, how to do this in PHP?

Well, there are no "documented" weak references. However, I figured
out by trial that if you obtain a php-reference to an object, it
doesn't bump the refcount.

Question #1: Is the fact that references to objects in the form
$objRef = &$obj don't bump the refcount of $obj an intended behavior
that can be counted on? If so, cool!

So, now that we have a way to do weak references, we should be able
to implement a reasonable memory management scheme for parent-child
objects.

Normally from the client side the interface should look something like:

$parent = new Parent();
$child = new Child();
$parent->addChild($child);

Where parent can have 0,n children and child can have 0,1 parent.

And all of parent's internal links to child should be refcounted, and
the internal links from child to parent are weak (not ref-counted).

So based on the above discovery about references, I tried to
implement this as such:

class Parent
{
public $children = array();

// add a child to our list. We want a ref-counted link here.
function addChild($child)
{
$this->children[] = $child; // refCounted desired in
parent->child link
$child->setParent($this);
}
}

class Child
{
public $parent;

// set the parent object. We want a non-ref-counted link here.
function setParent(&$parent)
{
// refCount NOT desired in child->parent link
$this->parent = &$parent;
}
}

Now, you'd expect this would work, but it doesn't. On a hunch, I
changed the client code to:

$parent = new Parent();
$child = new Child();
$parent->addChild($child);
$child->setParent($child); // new line here - you can successfully
create a reference to the object when not passed in as $this

Now, this works! However, it's not practical. The setParent call
should work from within the parent object....

So what I figured out is that $this is a "pseudo variable" according
to the docs, but I don't know what that means. Empirically I have
figured out that it means you cannot create a reference to it.

Is this a feature or a bug? What's the workaround?

This is a serious problem for PHP scripts that need to do things that
require large amounts of memory.

Please advise.

Thanks,
Alan

 

Navigation:

[Reply to this message]


Удаленная работа для программистов  •  Как заработать на Google AdSense  •  England, UK  •  статьи на английском  •  PHP MySQL CMS Apache Oscommerce  •  Online Business Knowledge Base  •  DVD MP3 AVI MP4 players codecs conversion help
Home  •  Search  •  Site Map  •  Set as Homepage  •  Add to Favourites

Copyright © 2005-2006 Powered by Custom PHP Programming

Сайт изготовлен в Студии Валентина Петручека
изготовление и поддержка веб-сайтов, разработка программного обеспечения, поисковая оптимизация