美文网首页
Java/Kotlin 中的弱引用解释(附插图)

Java/Kotlin 中的弱引用解释(附插图)

作者: 小城哇哇 | 来源:发表于2022-09-22 11:52 被阅读0次

当我在LeakCanary 库的文档中阅读更多内容以了解其工作原理时,我第一次听说了弱引用。但是当我用谷歌搜索它时,我并没有完全明白。此外,我阅读的所有示例都不实用,这使得理解这个概念变得更加困难。

Java 中有 4 种类型的引用:StrongSoftWeakPhatom

在本文中,我们将重点关注引用和弱引用。

强参考

每当我们创建任何对象时,它都是默认创建的引用。此引用将防止垃圾收集器 (GC) 销毁此对象。

例如,当我们创建一个名为Dummy;的类的实例时。如下图所示:

一个新类型的对象Dummy在内存中创建并myObject具有对其的强引用。

当我们在垃圾收集器运行myObject 之前尝试打印时;它将打印内存中对象的地址。

但是,当垃圾收集器运行时会发生什么?(我们通过写来强制GC运行来模拟这个System.gc())

对象将留在内存中,不会发生任何事情,因为这是我们所期望的(强引用防止 GC 破坏引用的对象)。

弱参考

这是来自维基百科的定义:

与强引用不同,弱引用是不保护被引用对象不被垃圾收集器收集的引用。

这意味着当我们创建一个对象的弱引用并且垃圾收集器运行时,它会立即从内存中清除该对象(如果没有其他对该对象的强引用)。

让我们举这个例子,然后我会解释什么时候我们可能需要这样的东西。

在上图中,我们创建了一个类型对象Dummy并对其myObject进行了弱引用。

所以在Dummy垃圾收集器运行之前,内存中现在有一个类型的对象,它是通过myObject使用弱引用来引用的。

我们现在将打印该虚拟对象,以确保它存在于内存中;对myObject变量使用.get()方法。

注意:该get()方法返回引用WeakReference的引用对象,如果引用的对象被清除,则返回 null。

所以Dummy我们创建的对象的内存地址会打印在控制台中,确认对象现在在内存中。

但是,如果我们现在运行垃圾收集器会发生什么?

在这里,您可以看到null已打印,并且Dummy实例已从内存中删除;这是有道理的,因为弱引用的描述表明,如果对对象存在弱引用并且垃圾收集器运行,它将从内存中删除该对象。

使用强引用和弱引用的示例

对于本例,我们有一个变量myObject,它保存对Dummy实例的强引用。

因此,让我们看看垃圾收集器运行之前和之后会发生什么。

在这里,Dummy()内存中的对象在 GC 运行后不会被销毁,因为有一个强引用( myObject) 来引用它。

而对于弱引用,它不会被 GC 清除,因为对象 ( Dummy()) 有另一个强引用( myObject) 附加到它上面。

这是弱引用的真正好处,它们只保留对对象的引用,只要它存在于内存中,并在与该对象相关的所有强引用都被清除时被清除。

Android 中的真实示例

我们都知道在单例中保留对上下文的引用是一个坏主意。如果您尝试这样做,Android Studio 会给您一个警告,说明:

不要将 Android 上下文类放在静态字段中(对 MySingleton 的静态引用,其中字段上下文指向 Context);这是内存泄漏

而这会导致内存泄漏

那么,如何解决这个问题呢?

使用弱引用!

以下是如何使用它:

现在,警告消失了,因为它不会导致泄漏,因为当MainActivity实例被销毁(onDestroy被调用)时,对其上下文的弱引用也将被销毁;所以不会发生内存泄漏。

结论

在开发 Android 应用程序、库或任何 Java/Kotlin 项目时,WeakReference 是一个非常重要的概念;但是,您必须确保正确使用它,以避免在代码中出现任何意外行为。

文章来源:https://blog.ahmedashour.me/weak-references-in-java-kotlin-explained-with-illustrations-android

相关文章

网友评论

      本文标题:Java/Kotlin 中的弱引用解释(附插图)

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