onMessage回调中实例化类和静态方法内存消耗差别怎么这么大?这是为何?

army

为了偷懒想用reload平滑重启,把控制改为实例化来调用,结果出现内存持续增长,又改回静态方法就正常了,想不明白?

public function onMessage(TcpConnection $c, Request $request): void
{
        .....
        //执行控制器
        //$res = $controller::$action($c->army); //调用静态方法内存使用正常
         $res = (new $controller)->$action($c->army);//用new实例化,内存持续增长
         $c->close($res);
}

class AppHide
{
   //控制器里的方法
    public function appHide($army): Response
    {
        ....
        return $army->res->withBody(Out::json(0, 'ok'));
    }
}

433 3 1
3个回答

nitron

试试在$c->close($res)后加上unset($res) ?

  • 暂无评论
xiuwang

估计是控制器实例没释放,在 __destruct(){} 里加个日志看下,是不是触发了析构函数。

据我所知, new 的类在以下情况下不会释放
1、类的属性保存了外部的长周期对象

class A {
    public $b;
    public function __construct($b)
    {
        // $b是一个长周期的对象,比如$worker
        $this->b = $b;
    }
}

2、类实例被保存到了静态数组中

class A {
    public static $instance = [];
    public function __construct()
    {
        static::$instance[] = $this;
    }
}
  • army 2023-05-20

    是的,应该是没有释放

Gin
$class = 'path\\classname';
if (!isset($instances[$class])) {
$instances[$class] = new $class; // 缓存类实例,避免重复初始化
}
🔝