首先,我想让你们知道这是一个理论问题而不是实际问题,我只是好奇弱引用对象是如何被释放的。
让我们快速记住java中的弱引用是什么。粗略地说 WeakReference
意思是在没有指向“我”的强引用的情况下,随时释放“我”,直到“我”仍然存在。另外,我们知道有很多不同的垃圾收集器使用不同的收集技术。例如,在过去,android是基于dalvik gc的,它是stop the world,字面意思是在内存清理期间应用程序被挂起。后来dalvik被art所取代-google编写的gc的新版本,由于它是并发的,所以速度要快得多。所以,现在我的问题来了-假设我们有一个从代码的某个点弱引用的对象,并且没有对这个对象的强引用,这意味着我们可以像往常一样访问和使用这个对象,直到收集器不决定回收它的空间为止。那么,如果收集器在通过 WeakReference
? 我是说密码呼叫 get()
方法来自 WeakRefernce
在收集器决定释放其内存的同时“精确”初始化。理论上,这两种类型的gc技术都是可能的。因为stop the world gc挂起应用程序-当应用程序访问此对象时,它可能会“准确地”挂起!对于并发gcs来说更容易-gc与应用程序执行并发发生。
这又是一个理论问题,我甚至不能百分之百肯定这是可能的!只是想了解java世界的一个边缘案例。
谢谢您!
当做,
安德烈
1条答案
按热度按时间enxuqcxy1#
没那么容易。为了保持堆的一致性,您不直接访问堆(至少在gc处于活动状态时是这样),而是通过典型gc创建的一些间接方式来访问它。你可以把它看作是一个“代理”,在gc的世界里,它们被称为
barriers
. 下面是某个热点收集器如何执行此操作的一个示例,或者您也可以阅读此示例。在非常,非常简单的话,即“准确地在访问过程中”,是不准确的。它将是一个原子弹
CAS
一个并发循环的操作,但如果它是一个停止世界循环-事情就更琐碎了。所以你永远无法访问WeakReference::get
同时gc作用于它。如果可以,并且gc允许这样做,堆的一致性就会消失,代码工作的任何保证也会消失。我的最后一点是,除非谷歌发明(并获得专利)一种算法来处理
WeakReferences
同时),WeakReferences
(和Soft/Phantom/Finalizer
)在完全暂停的情况下处理。