简体   繁体   English

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

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

First of all I want to let you know that this is more theoretical question than practical, I'm just curious how weakly referenced objects are deallocated.首先,我想让您知道,这是一个理论问题而不是实际问题,我只是好奇弱引用对象是如何被释放的。
Let's quickly remember what weak reference is in Java.让我们快速记住 Java 中的弱引用是什么。 Roughly speaking WeakReference means deallocate "me" any time you want when there are no strong references that are pointing to "me" until that "I" will remain alive.粗略地说, WeakReference意味着当没有指向“我”的强引用时,随时释放“我”,直到“我”仍然活着。 Also, we know that there are a lot of different garbage collectors that are using different collection techniques.此外,我们知道有很多不同的垃圾收集器使用不同的收集技术。 For example, in the past Android was based on Dalvik GC which was stop-the-world, which literally means that the app was suspended during memory cleaning.例如,过去 Android 是基于 Dalvik GC 的,它是 stop-the-world,字面意思是应用程序在内存清理期间暂停。 Later Dalvik was replaced with ART - new version of GC written by Google which is much faster since it is concurrent.后来 Dalvik 被 ART 取代——谷歌编写的新版 GC,因为它是并发的,所以速度要快得多。 So, now comes my question - assume that we have an object that is weakly referenced from some point of the code and there are no strong references to this object, this means that we can access and use this object as usual until collector will not decide to reclaim its space.所以,现在我的问题来了 - 假设我们有一个从代码的某个点弱引用的对象,并且没有对该对象的强引用,这意味着我们可以像往常一样访问和使用这个对象,直到收集器无法决定收回它的空间。 So, what will happen if the collector will try to deallocate the memory retained by this weakly referenced object exactly during accessing it via WeakReference ?那么,如果收集器在通过WeakReference访问它的过程中试图释放这个弱引用对象保留的内存,会发生什么? I mean the code calls get() method from WeakRefernce class "exactly" at the same time when collectors decides to free its memory.我的意思是,当收集器决定释放其内存时,代码“恰好”在同一时间从WeakRefernce类调用get()方法。 Theoretically it is possible with both types of GC techniques I described above.理论上,我上面描述的两种类型的 GC 技术都是可能的。 Since stop-the-world GC suspends the app - the app may be suspended "exactly" when it is accessing this object!由于 stop-the-world GC 挂起应用程序 - 应用程序可能在访问此对象时“恰好”挂起! For concurrent GCs it is even easier - GC happens concurrently to the app execution.对于并发 GC,它甚至更容易 - GC 与应用程序执行同时发生。
Again this is a theoretical question, I not 100% sure that it is even possible!这又是一个理论问题,我不能 100% 确定它甚至是可能的! Just trying to understand such an edge case of Java world.只是想了解 Java 世界的这种边缘情况。
Thank you !谢谢 !
Regards,问候,
Andre安德烈

It is not that easy.这并不容易。 To keep the heap consistent - you don't access the heap directly (at least when GC is active), you access it via some indirection that a typical GC creates.为了保持堆的一致性——你不直接访问堆(至少当 GC 处于活动状态时),你通过典型的 GC 创建的一些间接访问它。 You can think about it as a "proxy", in the GC world - these are called barriers .您可以将其视为 GC 世界中的“代理” - 这些称为barriers here is one example of how a certain HotSpot Collector does it, or you might want to read this also . 是某个 HotSpot 收集器如何执行操作的一个示例,或者您也可能想阅读此内容

In very, very simplified words that "exactly during accessing", is not exactly .用非常非常简单的话说,“恰好在访问期间”,不完全是. It will be an atomic CAS operation for a concurrent cycle, but if it is a stop-the-world cycle - things are far more trivial.这将是一个并发循环的原子CAS操作,但如果它是一个停止世界循环 - 事情要简单得多。 So you can never access a WeakReference::get at the same exact time a GC acts on it.所以,你永远不能访问WeakReference::get完全相同的时间,GC的作用就可以了。 If you could and a GC would allow that, heap consistency would be gone and so is any guarantee about your code working.如果可以并且 GC 允许这样做,那么堆一致性将消失,因此对您的代码工作的任何保证也将消失。

My last point is that unless google invented (and patented an algorithm to process WeakReferences concurrently), WeakReferences (and Soft/Phantom/Finalizer ) are processed under a full pause.我的最后一点是,除非谷歌发明(并申请了一种同时处理WeakReferences的算法的专利),否则WeakReferences (和Soft/Phantom/Finalizer )是在完全暂停的情况下处理的。

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

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