关于对象的生命周期问题?
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原来的呢?