虚拟引用对象
虚拟参考用于事后分析操作。 Java 规范规定,在幻像引用本身被清理之前,幻像引用对象不会被释放。
我的问题是:此功能(未释放对象)的用途是什么?
(我想到的唯一想法是允许本机代码对对象进行事后清理,但这不太令人信服)。
Phantom References serve for post-mortem operations.
The Java specification states that a phantom referenced object will not be deallocated until the phantom-reference itself is cleaned.
My question is: What purpose does this feature (object not deallocated) serve?
(The only idea i came up with, is to allow native code to do post-mortem cleanup on the object, but it isn't much convincing).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
编辑,因为我首先误解了这个问题:
从这里引用 http://www.memorymanagement。 org/glossary/p.html:
但我没有发现其他参考文献会说同样的话。
Edit, since I've misunderstand the question first:
Quoted from here http://www.memorymanagement.org/glossary/p.html:
But I found no other references which would say the same.
我能想到的唯一可以防止释放的好用例是某种 JNI 实现的异步数据源正在写入引用的对象,并且必须被告知停止写入 - 停止写入对象 -在内存被回收之前。 如果允许事先释放,一个简单的忘记处置()错误可能会导致内存损坏。
这是过去使用 Finalize() 的情况之一,并且可能导致了它的一些怪癖。
The only good use-case I can think of, that would prevent deallocation, is one where some kind of JNI-implemented asynchronous data source is writing into the referenced object, and must be told to stand down - to stop writing into the object - before the memory is recycled. If prior deallocation were allowed, a simple forgot-to-dispose() bug could result in memory corruption.
This is one of the cases where finalize() would have been used in the past, and probably drove some of its quirks.
我认为这个想法是让其他对象在原始对象所做的范围之外进行额外的清理。 例如,如果原始对象无法扩展以实现某些终结功能,则可以使用幻像引用。
更大的问题是 JVM 不保证对象将被最终确定,并且我认为扩展后也不能保证幻像引用在最终确定后执行其操作。
I think the idea is to let other objects do extra cleanup above and beyond what the original object does. For example, if the original object cannot be extended to implement some finalization stuff, you can use phantom references.
The bigger problem is that the JVM makes no guarantee that an object will ever be finalized, and I assume by extension no guarantee that phantom references get to do their thing post-finalization.
http://www.javalobby.org/java/forums/m91822870.html# 91822413
http://www.javalobby.org/java/forums/m91822870.html#91822413
对于没有生命周期管理机制但您正在使用需要显式生命周期管理的东西来实现的 API 来说,这是一个完美的解决方案。
特别是任何类型的 API,过去只使用内存中的对象,但您使用套接字连接或文件连接到其他更大的后备存储来重新实现,可以使用 PhantomReference 在调用之前“关闭”并清理连接信息。对象被 GC 处理,并且连接从未关闭,因为没有可以使用的生命周期管理 API 接口。
考虑将简单的 Map 地图移动到数据库中。 当地图引用被丢弃时,没有显式的“关闭”操作。 然而,如果您已经实现了写入缓存,您希望能够完成任何写入并关闭与“数据库”的套接字连接。
下面是我用于此类内容的一个类。 请注意,对 PhantomReferences 的引用必须是非本地引用才能正常工作。 否则,jit 会导致它们在退出代码块之前过早排队。
This is a perfect solution for APIs which don't have a lifecycle management mechanism, but which you are implementing with something which requires explicit lifecycle management.
In particular any sort of API which used to just use objects in memory, but which you've reimplemented using a socket connection or file connection to some other, larger backing store, can use PhantomReference to "close" and cleanup connection information prior to the object being GC'd and the connection never closed because there was no lifecycle management API interface that you could otherwise use.
Think of moving a simple Map map into a database. When the map reference is discarded, there is no explicit "close" operation. Yet, if you had implemented a write through cache, you'd like to be able to finish any writes and close the socket connection to the your "database".
Below is a class which I use for this kind of stuff. Note, that References to PhantomReferences must be non-local references to work correctly. Otherwise, the jit will cause them to be queued prematurely before you exit blocks of code.
它可以让你们两个拥有幻影缓存,这在内存管理方面非常有效。
简而言之,如果您有创建成本高昂但很少使用的巨大对象,则可以使用幻像缓存来引用它们,并确保它们不会占用更有价值的内存。 如果您使用常规引用,则必须手动确保不存在对该对象的引用。 您可以对任何对象进行同样的争论,但您不必手动管理幻影缓存中的引用。 只需要小心检查它们是否已被收集。
您还可以使用一个框架(即工厂),其中引用作为虚拟引用给出。 如果对象很多且寿命较短(即使用后被丢弃),这非常有用。 如果你有草率的程序员认为垃圾收集很神奇,那么清理内存非常方便。
It can allow you two have phantom caches which are very efficient in memory management.
Simply put, if you have huge objects that are expensive to create but seldom used, you can use a phantom cache to reference them and be sure they do not take up memory that is more valuable. If you use regular references you have to be manually make sure there are no references left to the object. You can argue the same about any object but you dont have to manually manage the references in your phantom cache. Just have to be carefull to check if they have been collected or not.
Also you can use a framework (i.e. a factory) where references are given as phantom references. This is useful if the objects are many and short lived (i.e. used and then disposed). Very handy for clearing memory if you have sloppy programmers that think garbage collection is magical.