Java GC : How does Java GC clears WeakReference object?

标签 java garbage-collection jvm weak-references dalvik

首先,我想让您知道,这是一个理论问题而不是实际问题,我只是好奇弱引用对象是如何被释放的。让我们快速记住 Java 中的弱引用是什么。粗略地说WeakReference意味着当没有指向“我”的强引用时,随时释放“我”,直到“我”仍然活着。此外,我们知道有很多不同的垃圾收集器使用不同的收集技术。例如,过去 Android 是基于 Dalvik GC 的,它是 stop-the-world,字面意思是应用程序在内存清理期间暂停。后来 Dalvik 被 ART 取代——谷歌编写的新版 GC,因为它是并发的,所以速度要快得多。所以,现在我的问题来了 - 假设我们有一个从代码的某个点弱引用的对象,并且没有对该对象的强引用,这意味着我们可以像往常一样访问和使用这个对象,直到收集器无法决定收回它的空间。那么,如果收集器在通过 WeakReference 访问它的过程中试图释放这个弱引用对象保留的内存,会发生什么情况。 ?我的意思是代码调用 get()方法来自 WeakRefernce在收集器决定释放其内存的同时“完全”类。理论上,我上面描述的两种类型的 GC 技术都是可能的。由于 stop-the-world GC 挂起应用程序 - 应用程序可能在访问此对象时“恰好”挂起!对于并发 GC,它甚至更容易 - GC 与应用程序执行同时发生。这又是一个理论问题,我不能 100% 确定它甚至是可能的!只是想了解 Java 世界的这种边缘情况。谢谢 !问候,安德烈

最佳答案

这并不容易。为了保持堆的一致性——你不直接访问堆(至少当 GC 处于 Activity 状态时),你通过典型的 GC 创建的一些间接访问它。你可以把它想象成一个“代理”,在 GC 的世界里——它们被称为 barriers . here是某个 HotSpot Collector 如何做到这一点的一个示例,或者您可能想阅读 this also .
用非常非常简单的话来说,“恰好在访问期间”,并不完全是。这将是一个原子 CAS并发周期的操作,但如果它是一个停止世界的周期 - 事情要简单得多。所以你永远无法访问 WeakReference::get在同一时间 GC 对其进行操作。如果可以并且 GC 允许这样做,那么堆一致性将消失,因此对您的代码工作的任何保证也将消失。
我的最后一点是,除非谷歌发明了(并申请了一种算法来同时处理 WeakReferences),否则 WeakReferences (和 Soft/Phantom/Finalizer )在完全暂停下处理。

关于Java GC : How does Java GC clears WeakReference object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64969727/

相关文章:

java - 如何调整G1GC以减小内存占用量?

java - 使用 SWT 创建 GUI 时出现 Event.gc 错误

java - 添加从Mysql服务器到Java应用程序的通知推送

java - Mockito 模拟具有相似签名的相同命名方法

java - JSP 片段中的未知标记和未定义函数

memory-leaks - 第 2 代堆和大对象堆爬升

java - CMS 垃圾收集器——它什么时候运行?

java - 防止 JVM 写入 System.out 或从 System.in 读取

java - 编译器 asm 字节码表达式

java - 用java编写二维数组