繁体   English   中英

Java GC:Java GC 如何清除 WeakReference 对象?

[英]Java GC: How does Java GC clears WeakReference object?

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

这并不容易。 为了保持堆的一致性——你不直接访问堆(至少当 GC 处于活动状态时),你通过典型的 GC 创建的一些间接访问它。 您可以将其视为 GC 世界中的“代理” - 这些称为barriers 是某个 HotSpot 收集器如何执行操作的一个示例,或者您也可能想阅读此内容

用非常非常简单的话说,“恰好在访问期间”,不完全是. 这将是一个并发循环的原子CAS操作,但如果它是一个停止世界循环 - 事情要简单得多。 所以,你永远不能访问WeakReference::get完全相同的时间,GC的作用就可以了。 如果可以并且 GC 允许这样做,那么堆一致性将消失,因此对您的代码工作的任何保证也将消失。

我的最后一点是,除非谷歌发明(并申请了一种同时处理WeakReferences的算法的专利),否则WeakReferences (和Soft/Phantom/Finalizer )是在完全暂停的情况下处理的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM