美文网首页Android开发Android技术知识
怎么解决引用计数 GC 的循环引用问题?

怎么解决引用计数 GC 的循环引用问题?

作者: Android开发架构师 | 来源:发表于2020-08-07 22:19 被阅读0次

作者:Android面试官

引用计数方式 GC 存在循环引用问题,导致无法辨别无用对象,而 GC ROOT 方式不存在循环引用的问题

引用计数和 GC ROOT 的实现机理很易理解,面试时大家都能流利应答,那怎么才能脱颖而出呢?思考一个问题:不通过 GC ROOT,仍使用引用计数方式,怎么解决它的循环引用问题?

解答此问题前,通过目标驱动法来想象一下,若 Get 了此知识点,可以这样应用到面试中:

面试官: 说一下垃圾回收机制吧

我: ...可以通过强、弱引用计数结合方式解决引用计数的循环引用问题,实际上 Android 的智能指针就是这样实现的...

智能指针

智能指针在整个 Android 工程中使用很广泛,在 binder 相关源码可以看到 sp、wp 类型的引用:

 sp<IBinder> result = new BpBinder(handle);

 wp<IBinder> result = new BpBinder(handle);
复制代码

sp 即 strong pointer 强指针引用;wp 是 weak pointer 弱指针引用。

在 Java 中我们不用关心对象的销毁及内存释放,GC 机制会自动辨别回收无用对象,而 智能指针 就是 native 层一个小型的 GC 实现。

智能指针以引用计数的方式来标识无用对象,使用智能指针的对象需继承自 RefBase,RefBase 中维护了此对象的强引用数量和弱引用数量。

强指针 sp 重载了 "=" 运算符,在引用其他对象时将强引用计数 +1,在 sp 析构函数中将强引用计数 -1,当强引用计数减至 0 时销毁引用的对象,这样就实现了对象的自动释放。

弱指针引用其他对象时将弱引用计数 +1,在 wp 析构函数中将弱引用计数 -1,当强引用计数为 0 时,不论弱引用计数是否为 0 都销毁引用的对象。

如何解决循环引用问题

只靠强引用计数方式,会存在循环引用的问题,导致对象永远无法被释放,弱引用就是专门用来解决循环引用问题的:

若 A 强引用了 B,那 B 引用 A 时就需使用弱引用,当判断是否为无用对象时仅考虑强引用计数是否为 0,不关心弱引用计数的数量

这样就解决了循环引用导致对象无法释放的问题,但这会引发野指针问题:当 B 要通过弱指针访问 A 时,A 可能已经被销毁了,那指向 A 的这个弱指针就变成野指针了。在这种情况下,就表示 A 确实已经不存在了,需要进行重新创建等其他操作

智能指针自定义规则

智能指针并不是固定的 "当强引用计数为 0 时,不论弱引用计数是否为 0 都销毁引用的对象" ,而是可以自定义规则。RefBase 提供了 extendObjectLifetime() 方法,可以用来设置引用计数器的规则,不同规则对删除目标对象的时机判断也是不一样的,包括以下三种规则:

OBJECT_LIFETIME_STRONG:只有在这个对象内存空间中的强计数器值为 0 的时候才会销毁对象

OBJECT_LIFETIME_WEAK:只有在这个对象内存空间中的强计数器和弱计数器的值都为 0 的时候才会销毁对象

OBJECT_LIFETIME_MASK:不管这两个计数器是不是都为 0,都不销毁对象,即与一般指针无异,还是要自己手动去释放对象

喜欢本文的话,不妨顺手给我点个小赞、评论区留言或者转发支持一下呗~

相关文章

  • Android面试:怎么解决引用计数 GC 的循环引用问题?

    引用计数方式 GC 存在循环引用问题,导致无法辨别无用对象,而 GC ROOT 方式不存在循环引用的问题 引用计数...

  • gc-roots-reachability-analysis-s

    savepoint, gc roots 对象是否已死?引用计数解决不了循环引用问题可达性分析(从 gc roots...

  • 怎么解决引用计数 GC 的循环引用问题?

    作者:Android面试官 引用计数方式 GC 存在循环引用问题,导致无法辨别无用对象,而 GC ROOT 方式不...

  • GC

    引用计数法 高效,但无法解决循环引用的问题。 Java中采用“可达性分析”方法 通过一系列的“GC Root”...

  • 垃圾收集

    判断对象是否已死: 引用计数法(很难解决对象之间相互循环引用的问题) 可达性分析算法 可作为GC Roots的对象...

  • JVM-对象已死判断

      1)引用计数器法(无法解决循环引用) 2)枚举根节点做可达性分析。  GC Roots:一组必须活跃的引用。 ...

  • jvm 垃圾回收

    算法 引用计数法 Reference Counting 优点:实现简单 缺点:循环引用无法解决 伴随性能问题(计数...

  • swift重温笔记(自动引用计数)

    自动引用计数的工作机制 自动引用计数实践 类实例之间的循环强引用 解决实例之间的循环强引用 闭包引起的循环强引用 ...

  • java之循环引用

    在学习java内存模型及垃圾回收时提到了引用计数法无法解决循环引用的问题,心里一直在思考怎么才是循环引用。nett...

  • Swift Tour Learn (九) -- Swift 语法

    本章将会介绍 自动引用计数的工作机制自动引用计数实践类实例之间的循环强引用解决实例之间的循环强引用闭包引起的循环强...

网友评论

    本文标题:怎么解决引用计数 GC 的循环引用问题?

    本文链接:https://www.haomeiwen.com/subject/txaqdktx.html