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

引用计数智能指针自引用循环导致内存泄漏问题求解

问题核心

当前实现的ref是强引用智能指针,持有对象时会递增引用计数。对象内部持有自身强引用时,外部所有引用释放后,对象引用计数仍为1,无法触发析构,属于自引用类型的循环引用问题。

解决方案


方案1:拆分强/弱引用类型(最通用,推荐优先使用)

额外实现不增加引用计数的弱引用智能指针weak_ref:

  • 弱引用仅持有对象观测权,不会阻止对象销毁
  • 访问对象前调用weak_ref的lock()方法尝试升级为强引用ref,升级成功则对象存活可正常访问,升级失败说明对象已销毁
  • 原有示例仅需将内部成员m_ref类型从ref<Object>改为weak_ref<Object>即可,自引用不会增加引用计数,外部引用释放后对象会正常析构

改后代码示例:

class Derived : public Object {
public:
    static ref<Object> Create() { return ref<Object>(new Derived()); }

private:
    Derived() : m_ref(this) // 弱引用赋值不会增加引用计数
    {
        // 访问对象前先升级为强引用
        if (ref<Object> strong_ref = m_ref.lock()) {
            // 正常访问对象逻辑
        }
    }
    weak_ref<Object> m_ref;
};

方案2:实现enable_ref_from_this机制(适用于需要持有自身强引用的场景)

如果业务确实需要对象内部持有自身强引用(比如异步回调要保证执行时对象存活),给基类Object新增继承enable_ref_from_this辅助类:

  • 辅助类内部默认存储指向当前对象的弱引用
  • 对外提供ref_from_this()方法,调用时将内部弱引用升级为强引用返回
  • 要求对象必须通过ref智能指针托管,禁止栈上创建、禁止直接使用裸指针,你现有的Create工厂方法符合使用要求

改后代码示例:

// 基类新增继承辅助类
class Object : public enable_ref_from_this<Object> {
    // 原有基类逻辑不变
};

class Derived : public Object {
public:
    static ref<Object> Create() { 
        auto obj = ref<Object>(new Derived());
        // 构造完成后通过ref_from_this获取自身强引用赋值
        obj->m_ref = obj->ref_from_this();
        return obj;
    }

private:
    Derived() = default;
    ref<Object> m_ref;
};

方案3:手动断环(兜底方案,不推荐)

如果不想改动现有智能指针实现,给Object基类新增dispose接口,派生类实现接口时主动将内部持有的所有强引用置空,断开循环引用环。需要销毁对象前主动调用dispose方法即可。该方案依赖手动调用,遗漏就会出现内存泄漏,仅适合临时修复场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:27:02