首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在PHP中获取对象的引用计数?

在PHP中获取对象的引用计数?
EN

Stack Overflow用户
提问于 2010-09-22 05:36:04
回答 5查看 4.3K关注 0票数 17

我意识到对这个问题的下意识反应是“你不会”,但请听我说完。

基本上,我在SQL上的活动记录系统上运行,为了防止相同数据库行的重复对象,我在工厂中为每个当前加载的对象保留一个“数组”(使用自动增量“id”作为键)。

问题是,当我偶尔尝试通过这个系统处理90,000+行时,PHP遇到了内存问题。这很容易通过每几百行运行一次垃圾收集来解决,但不幸的是,由于工厂存储了每个对象的副本-PHP的垃圾收集不会释放这些节点中的任何一个。

我能想到的唯一解决方案是检查存储在工厂中的对象的引用计数是否等于1(即没有引用该类的对象),如果是,则释放它们。这将解决我的问题,但是PHP没有引用计数方法吗?(除了debug_zval_dump,但这几乎是不可用的)。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-09-27 21:29:23

似乎最好的答案仍然是获取引用计数,尽管debug_zval_dump和ob_start太难看了,无法包含在我的应用程序中。

相反,我用refcount()函数编写了一个简单的PHP模块,该函数可在:http://github.com/qix/php_refcount上找到

票数 6
EN

Stack Overflow用户

发布于 2010-09-27 12:32:46

Sean的debug_zval_dump函数看起来会告诉你引用计数,但实际上,从长远来看,引用计数并不能帮到你。

您应该考虑使用有界数组作为缓存;如下所示:

<?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;
   }
}

在这里,getKey()为您想要存储的对象返回一些惟一的id。这依赖于PHP记住插入到其哈希表中的顺序;每次添加新元素时,都会将其逻辑附加到数组中。

get()函数确保您访问的对象保留在数组的末尾,因此数组的前端将是最近最少使用的元素,当我们确定空间不足时,这是我们想要处理的元素;array_shift()为我们做了这件事。

这种方法也被称为最近使用的缓存,或MRU缓存,因为它缓存最近使用的项目。这样做的想法是,您更有可能访问最近访问过的项目,因此将它们保留在身边。

你在这里得到的是控制你所保留的对象的最大数量的能力,并且你不必去查看那些故意难以访问的php实现细节。

票数 6
EN

Stack Overflow用户

发布于 2010-09-22 05:55:49

是的,你绝对可以从PHP获取refcount。不幸的是,refcount不容易获得,因为它没有内置到PHP中的访问器。没关系,因为我们有PREG!

<?php
function refcount($var)
{
    ob_start();
    debug_zval_dump($var);
    $dump = ob_get_clean();

    $matches = array();
    preg_match('/refcount\(([0-9]+)/', $dump, $matches);

    $count = $matches[1];

    //3 references are added, including when calling debug_zval_dump()
    return $count - 3;
}
?>

来源:PHP.net

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3764686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档