-
Notifications
You must be signed in to change notification settings - Fork 233
Open
Description
文件 https://github.com/zanphp/coroutine/blob/master/src/Task.php 第50行如下:
public function __construct(\Generator $coroutine, Context $context = null, $taskId = 0, Task $parentTask = null)
{
$this->coroutine = $this->caughtCoroutine($coroutine);
$this->taskId = $taskId ? $taskId : TaskId::create();
$this->parentTask = $parentTask;
if ($context) {
$this->context = $context;
} else {
$this->context = new Context();
}
$this->scheduler = new Scheduler($this);
}这个 $this->scheduler = new Scheduler($this); 这个会把 Scheduler 放在自己的寄存器里,然而 Scheduler 这个对象又把 Task 放在了自己的 task 变量里。形成了相互引用。在处理完毕后并不会释放对象,只有在php垃圾回收机制下才会被清理。不信的话,可以加
public function __destruct()
{
echo "i'm unset";
}会发现并未协程执行完毕后这个方法并未被执行,内存中还存在。
建议Task中加:
public function release()
{
# 移除对象,避免相互引用导致的对象不可释放
if (isset($this->scheduler))
{
$this->scheduler->release();
unset($this->scheduler);
}
}Scheduler 中加:
public function release()
{
unset($this->task);
}并在 Signal::TASK_KILLED 和 Signal::TASK_DONE 时调用。这样在协程处理完毕后,会立即释放对象,避免内存溢出。
sukui, isliuyaoyao, gsons, qiujiafei and lishumingooisliuyaoyao, ekk0 and lishumingoosukui and isliuyaoyaosukui and isliuyaoyao
Metadata
Metadata
Assignees
Labels
No labels