pinguo/php-msf

关于对象的生命周期问题?

wuchuguang opened this issue · 4 comments

class Test extens Controller{
     private $server;
     public function __construct($controllerName, $methodName){
            parent::__construct($controllerName, $methodName);
            $this->server = $this->server ?? $this->getObject(Server::class);
     }
}
class Server extens Core{
    private $mode;
    public function __construct(){
          $this->model = $this->getObject(MyModel::class);
    }
   public function destroy()
    {
        parent::destroy(); // TODO: Change the autogenerated stub
        $this->model = null;
        echo "destory\n";
    }
    public function __destruct()
    {
        echo "__destruct\n";
    }
}

多worker时=4,
前4次请求会Test 调用:?? $this->getObject(Server::class);//因为每个worker都会初始一次server
这4次请求是很正常的。
第5次请求时,?? $this->getObject(Server::class);不会调用了。因为private $server被前4次设值了。

导至Server的__construct不会调用到。
那么为什么前4次明明private $server是非public的,而它的Server实例下的destroy会被调用到。
而且__destruct析构函数也调用了。

第五次没有?? $this->getObject(Server::class);,那$server中的$model就不会this->getObject(MyModel::class);//那这时的$model一直是null了。。。

如果这不是个bug.那我们只有放弃了。。。msf

1.这个问题我完全理解,示例代码中$server通过对象池生成了,对象池策略默认是要自动走归还和释放逻辑;
2.那么为什么前4次明明private $server是非public的,而它的Server实例下的destroy会被调用到。不管属于是public,private,destory方法和析构一定会调用,而这里destory方法里面显示$this->model = null
3.第五次没有执行构造方法,是因为你$server本身是private的,的确不为null,所以就没有去对象池获取对象;

总结一下,还是对对象池策略没有理解清楚。

解决方案,不要在private修饰$server和$mode,不理解你为什么要这么用?

@xudianyang 想充份压炸对象池提供的服务。
后面我想了想,跟你第二条的一样。
因为对象池没有办法存对象关联(关系),所以无法感知$server这个对象不该回收(调用destory).
runkit支持7.1了,如果想达到我心想的,估计可以试试这个.

还有个问题,private/protected不会自动处理的属性,是否必需
destory(){
xxx= null;//或unset($this->xxx)
}
手动消毁,才不会导致后面对象池错乱/溢出呢。。。
因为新的__construct又会this->getObject();//出来。还是说这里会get原来的呢?