You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中unset实例后内存未释放的原因及引用分析

实例赋值给自身静态变量后unset无法释放内存的原因解析

问题描述

定义了一个简单的类,并将其实例赋值给自身的静态变量。使用unset销毁该实例后,发现内存并未真正释放,需解析以下问题:

  • $app与$foo指向的是同一个实例吗?
  • 为何unset($foo)后实例内存未被释放?

代码示例

class Foo {
    public static $app;

    public function __construct() {
        self::$app = $this;
    }
}

$foo = new Foo;

unset($foo);

var_dump($foo);

var_dump(Foo::$app);

执行结果

Warning: Undefined variable $foo in /var/www/index.php on line 16
NULL
object(Foo)#1 (0) { }

原因解析

  1. $app和$foo指向同一个实例
    执行$foo = new Foo时,创建了Foo类的实例,$foo变量持有该实例的引用;构造函数中self::$app = $this,$this代表当前创建的实例,因此静态变量Foo::$app也持有同一个实例的引用,二者指向完全相同的对象。

  2. PHP引用计数机制导致内存未释放
    PHP采用引用计数管理内存:每个对象实例都有一个引用计数器,记录当前有多少个变量/指针指向它。

    • 创建实例时,$foo指向它,引用计数为1;
    • 构造函数中self::$app = $this,新增一个引用,计数变为2;
    • 执行unset($foo)仅销毁$foo变量对实例的引用,引用计数降到1,但静态变量Foo::$app仍持有该实例的引用,计数未到0,PHP垃圾回收机制不会释放该实例的内存。

只有当Foo::$app也被销毁(比如执行unset(Foo::$app)),实例引用计数降到0时,内存才会被真正释放。

内容的提问来源于stack exchange,提问作者Mark Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:36:23