内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用
基本上我在一个SQL上运行在一个活动记录系统上,为了防止同一个数据库行出现重复对象,我在工厂里保留了一个'数组',每个当前加载的对象(使用一个自动增量'id'作为关键字)。
问题是,当我尝试在奇怪的场合通过这个系统处理90,000多行时,PHP遇到了内存问题。这很容易通过每隔几百行运行一次垃圾收集来解决,但不幸的是,由于工厂存储了每个对象的副本--PHP的垃圾收集将不会释放任何这些节点。
我能想到的唯一解决方案是检查工厂中存储的对象的引用计数是否等于1(即没有引用该类),并且如果这样可以释放它们。这将解决我的问题,但PHP没有引用计数方法?(除了debug_zval_dump,但几乎不可用)。
尽管debug_zval_dump和ob_start在我的应用程序中太难看了,但似乎最好的答案仍然是引用计数。
相反,我用一个refcount()函数编写了一个简单的PHP模块,可在http://github.com/qix/php_refcount获取。
你应该考虑使用有界数组作为缓存;如下所示:
<?php class object_cache { var $objs = array(); var $max_objs = 1024; // adjust to fit your use case function add($obj) { $key = $obj->getKey(); // remove it from its old position unset($this->objs[$key]); // If the cache is full, retire the eldest from the front if (count($this->objs) > $this->max_objs) { $dead = array_shift($this->objs); // commit any pending changes to db/disk $dead->flushToStorage(); } // (re-)add this item to the end $this->objs[$key] = $obj; } function get($key) { if (isset($this->objs[$key])) { $obj = $this->objs[$key]; // promote to most-recently-used unset($this->objs[$key]); $this->objs[$key] = $obj; return $obj; } // Not cached; go and get it $obj = $this->loadFromStorage($key); if ($obj) { $this->objs[$key] = $obj; } return $obj; } }