当前位置: 首页 > 面试题库 >

空队列的PhantomReference

南宫俊喆
2023-03-14
问题内容

Java允许编写:

new PhantomReference(new Object(), null)

在这种情况下new Object()将被收集?

据我了解,幻影引用是finalize() 方法使用的替代方法。

在队列中出现引用后,我需要执行一些其他操作,然后运行 clear()

Java Doc保留:

可以使用空队列创建幻影引用,但是这种引用完全没有用:其get方法将始终返回null,并且由于它没有队列,因此永远不会入队。

如果它永远不会排队,那意味着什么?

据我了解,这意味着在完成方法调用之后,引用不会添加到referenceQueue中。因此可能导致:
1.对象存储器将立即被清除
2.对象存储器将不会被清除

哪种情况正确?


问题答案:

嗯,就像您注意到的那样,a
PhantomReference不会自动清除。这意味着,只要您对保持强烈引用PhantomReference,该参照对象就可以幻影地到达。正如文档所述:“
可以通过幻像引用访问的对象将保持不变,直到清除所有此类引用或自身无法访问为止。

但是,考虑何时无法访问对象(现在我正在谈论“幻像引用本身”)可能会导致很多意外。特别是因为很有可能该参考对象(不提供有用的操作)随后将不再被触摸。

由于PhantomReference没有队列将永远不会排队,并且其get()方法将始终返回null,因此它确实没有用。

那么,为什么构造函数允许构造这样一个无用的对象呢?好吧,第一个版本(1.2)的文档指出,NullPointerException如果队列为,它将抛出a
null。该语句一直持续到1.4,然后Java
5是第一个包含该语句的版本,尽管无用,您
也可以PhantomReference无队列地构造a
。我的猜测是,它总是继承超类的行为,即允许null排队,与文档相矛盾,并且很晚才被发现,因此决定保持兼容性并改编文档,而不是更改行为。

问题(甚至更难回答)是为什么a
PhantomReference不会自动清除。该文档只说一个幻影可到达对象会保留下来,这是未清除的结果,但是没有解释为什么它有任何相关性。

这个问题已经提出来了,但是答案并没有真正令人满意。它说“允许
对象被垃圾回收 之前
执行清理”,这甚至可能与设计决策者的想法相符,但是由于清理代码无法访问该对象,因此它是在对象执行之前还是之后都没有关系。在回收对象之后。如上所述,由于此规则取决于PhantomReference对象的可访问性,需要对对象进行可达性的优化代码转换,因此甚至有可能PhantomReference在清理代码完成之前将对象与实例一起回收,而没有任何人注意。

我在2013 年的HotSpot开发人员邮件列表中也发现了类似的问题,但也没有答案。

有一个增强请求JDK-8071507可以更改该行为并清除PhantomReferences,就像其他行为一样,对于Java
9的状态为“已修复”,实际上,其文档现在指出已像其他任何参考文献一样将其清除。

不幸的是,这意味着从Java 9开始,我文章开头的答案将是错误的。然后,无论您是否强烈引用该实例new PhantomReference(new Object(), null),新创建的Object实例都将立即具有进行垃圾回收的资格PhantomReference



 类似资料:
  • 我发送消息从JavaSpring Boot应用程序到消费者是Python应用程序。 除了输入命令rabbitmqctl list\u queues时,一切正常,它显示视频队列0,这意味着队列中没有消息。 消费者正在接收消息并执行一些长过程;所以如果我连续发送多条消息,应该会有一些消息在队列中等待。我说得对吗? 制片人: 消费者 在哪里可以看到我声明的队列上的消息?因为虽然我知道队列中有消息,但使用

  • 问题内容: 我正在使用RQ,我有一个队列包含数千个项目,而另一个队列我创建了一段时间用于测试,现在已经空了并且没有使用。我想知道如何从队列中删除所有作业,然后完全删除队列? 道歉的基本问题,但我无法在RQ文档中找到有关此信息,对于Redis和RQ来说,我都是新手…预先感谢! 问题答案: RQ提供了使任何队列为空的方法: 如果仍然存在,也可以对队列执行相同的操作。 清理使用 安装rq-dashboa

  • 我有一个多线程应用程序,其中一个线程将项目放入< code>BlockingQueue中,多个线程从中取出项目进行处理。问题是关于从队列中获取项目,目前它是这样实现的: 根据<code>BlockingQueue的JavaDoc。take()它检索并删除队列的头部,如果需要,等待元素可用,对于<code>PriorityBlockingQueue直到队列中出现一个项目: 实现我们的逻辑的另一种方法

  • 简介 Lumen 的队列服务给不同的后端队列提供统一的 API。队列允许你延迟处理耗时的任务,例如在远程服务器上执行任务,直到您的应用程序可以快速的处理 Web 应用程序的请求。 就像该框架的许多其他部分一样,Lumen 的队列服务跟 Laravel 的队列服务功能相同。因此,如果要了解更多关于 Lumen 的队列,则可以参阅 full Laravel queue documentation. 配

  • 简介 {tip} 现在,Laravel 为你的 Redis 队列提供了 Horizon,一个拥有漂亮的仪表盘的配置系统。 查看完整的 Horizon 文档 Horizon documentation 了解更多信息。 Laravel 队列为不同的队列后台服务提供了统一的 API,比如 Beanstalk, Amazon SQS, Redis, 甚至是关系型数据库。队列可以使你延迟处理一些耗时的任务,

  • 队列是先进先出(FIFO, First-In-First-Out)的线性表,只允许在后端(rear)进行插入操作,在前端(front)进行删除操作。