PHP Object-Caching and Reference Counting
| From: | Lars Schultz | Date: | Fri, 19 Jan 2007 15:21:18 +0000 |
| Subject: | PHP Object-Caching and Reference Counting | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-27539@lists.php.net to get a copy of this message | ||
Hello there...
I am making my debut appearance here hoping that I am not giving offense to anyones well honed php-instincts or programming practices with my feature-request. This is what it comes down to, I guess. A Feature Request for some meta-info on the instantiated PHP-Objects. Specifically I want to know how many references are currently pointing to any one object. Since PHP's Memory Management is based on Reference-Counting this information should already be available "somewhere". Not knowing any php-source-code internals, I can't even guess at the problems which prohibit the implementation of such a feature. Nevertheless I'd like to point out an advantage to the community if the reference-count were available.
I have been working on a large project for 6 years now and I got to a point where I'd like to cache certain objects singleton-like. To better explain my problem I provide this small example which surely is error-prone but should get the basic idea across.
<?
class MyObject {
private static $instances = array();
protected $id;
private function __constructor($id){
$this->id = $id;
}
/**
* Returns an instance of the class.
* If no object was instantiated with the given $id before,
* it will instantiate a new object which will be associated with the given $id.
*
* It will also check the current memory-usage and if its used up for more than
* 80% it will call the collect() method.
*
* @param int $id
* @return MyObject
*/
public static function getInstance($id){
if ( !isset(self::$instances[$id]) ) {
//check the used up memory wether to collect unused objects or not
if ( memory_get_usage() > ini_get('memory limit')*0.8 ) self::collect();
self::$instances[$id] = new MyObject($id);
}
return self::$instances[$id];
}
/**
* Removes any object from the cache-list which is not referenced anymore.
* (safe for the list and the local-reference to it)
*/
public static function collect(){
foreach( self::$instances as $id => $instance ) {
if ( reference_count($instance) < 3 ) unset(self::$instances[$id]);
}
}
}
?>
As you can see I boldly used the function reference_count(Object) even though it doesn't exist. This is exactly what I'd need to allow my concept to work. I keep thinking of any other solutions, but up until now, I didn't find any better solution for this problem. Of course I can always ignore the memory usage and hope that it wont hit the limit...but hoping is a rather ethereal and mystic idea which doesn't go well with my preferred down-to-earth 1 plus 1 equals 2 programming.
I know that a lot of you may say: Why do need to do that?...and I'd have to think for 3 days and then write for 4 days and would give up. It seems like a nice solution to me and if any of you have an idea as to how I could implement this differently, please feel free to point it out to me.
Thanks for reading this far.
Lars