Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java GC如何知道何时收集对象?_Java_Garbage Collection - Fatal编程技术网

Java GC如何知道何时收集对象?

Java GC如何知道何时收集对象?,java,garbage-collection,Java,Garbage Collection,我知道GC收集的对象没有指向所讨论对象的引用,但是在侦听器对象事件中会发生什么呢 假设您有一个AnimationDelegate,它侦听来自DataSupplier的数据。当DataSupplier接收数据并向AnimationDelegate触发事件时,该代理将使图形无效(/update/redraw等)。现在假设屏幕被禁用、移除,或者通过各种方式,图形无法再绘制并被收集。AnimationDelegate仍注册到DataSupplier。GC如何知道如何收集它?如果有人在graphicsfi

我知道GC收集的对象没有指向所讨论对象的引用,但是在侦听器对象事件中会发生什么呢


假设您有一个
AnimationDelegate
,它侦听来自
DataSupplier
的数据。当
DataSupplier
接收数据并向
AnimationDelegate
触发事件时,该代理将使
图形无效(/update/redraw等)。现在假设屏幕被禁用、移除,或者通过各种方式,图形无法再绘制并被收集。
AnimationDelegate
仍注册到
DataSupplier
。GC如何知道如何收集它?如果有人在graphics
finalize()
方法中注销代理?

它将只知道您是否删除了引用(将其清空)

但是,不要在finalize()上执行此操作。这很糟糕。应该有其他生命周期方法可用于清理侦听器(观察者)类型的对象


顺便说一句,observer模式因产生内存泄漏而臭名昭著,因为GC由于延迟引用而无法收集。

恐怕答案不符合格式:)由Brian Goetz开始:如果你对GC感兴趣,他是一个非常适合阅读的人

基本上,一旦无法从活动线程访问对象,就会收集它。即使在一个JVM中,实际的算法也会有所不同,但要点是一样的:无法访问的是垃圾。可触及的东西不是垃圾。简单

在您的示例中,GC不会收集
图形
,因为它可以从
AnimationDelegate
访问,而
DataSupplier
又可以从
数据供应商
访问(通过订阅),该数据供应商应该可以从某个活动线程访问。所以答案是:你的假设是错误的;GC不会在这里收集任何东西

要回答您的问题,请取消订阅您不需要的所有内容


正如@rfeak正确地说的那样,
finalize()
是一个巨大的禁忌。正确使用它几乎是不可能的,而且很容易出错。也就是说,当您需要释放资源时,可以将其用作备份解决方案。但是一般来说,即使从未调用过
finalize()
,您的应用程序也必须能够正常工作。

这一切都取决于您使用的JVM和GC。来自JDK的大多数默认GC使用所谓的“跟踪收集器”,它只从给定的根对象集开始,跟踪从该集可以访问的所有对象。内存中的所有其他对象都被视为垃圾并被删除。因此,循环引用不是真正的问题,除非其中一个对象可以从根集访问

什么是对象的根集?如果内存服务于右根,那么可以在以下位置找到:程序寄存器、每个线程堆栈中的局部变量和静态变量

要查看您的对象是否将被GC化,我们将了解更多有关应用程序设计的信息


@编辑:哦,我差点忘了:。这是一个很好的概述,说明了它是如何工作的。

它使用了引用计数。基本上,只要不再有指向对象的指针,它就会在下一个GC过程中被垃圾收集。实际上,它完全依赖于实现。我记得有些人仍然使用引用计数,但我不认为HotSpot JVM附带的GC会这样做。如果你想了解它的技术,HotSpot JVM附带了一个“标记和扫描”GC算法。但不管采用哪种算法,净效果都是一样的。当GC运行时,不再被引用的对象将被回收。无论这些没有活动引用的对象是通过引用计数、标记和扫描或其他算法来识别,这在很大程度上都是无关紧要的。。。不,这取决于算法。正如你从我的或其他评论中所读到的,引用计数可能会遇到循环引用的问题,而跟踪收集器不会有这个问题。这就是我意识到的(尽管私下希望我错了…)。我坐在这里做我的绘图工作,我突然想到了这个想法。第一句话似乎不完全正确,java gc可以处理引用中的循环,而“只有当你将它们置零时它才会知道”的天真模型则不能。假设您有一个模型,其中包含引用。假设对象A的字段指向对象B,反之亦然。如果它们都不能从您的程序中访问,那么它们将被垃圾收集——尽管它们的引用没有为null。虽然我可能忽略了问题的要点:\n我没有评论循环检测,我知道GC可以处理循环检测。我是在评论OP描述的悬而未决的听众问题。GC不能处理这个问题。代码必须明确地清理这些引用,我建议不要通过finalize()完成。