堆转储中不可能的Java内存引用
我在晚上7:41进行了一次Java堆转储,我正在使用Eclipse内存分析工具进行分析。堆转储包括20个会话对象 在我的堆中的其中一个会话对象上使用Path to GC Roots命令可以显示以下3个对会话对象的引用堆转储中不可能的Java内存引用,java,memory-leaks,garbage-collection,Java,Memory Leaks,Garbage Collection,我在晚上7:41进行了一次Java堆转储,我正在使用Eclipse内存分析工具进行分析。堆转储包括20个会话对象 在我的堆中的其中一个会话对象上使用Path to GC Roots命令可以显示以下3个对会话对象的引用 来自终结器线程拥有的“未终结”链接列表的终结器引用。我的目标是第三行要完成 消息处理程序线程对会话对象的强引用,消息处理程序线程本身从计划在晚上7:11运行的清理计时器任务中引用 WeakHashMap$项对会话对象的弱引用。WeakHashMap通过静态强引用保持活动状态 当
- 来自终结器线程拥有的“未终结”链接列表的终结器引用。我的目标是第三行要完成
- 消息处理程序线程对会话对象的强引用,消息处理程序线程本身从计划在晚上7:11运行的清理计时器任务中引用
- WeakHashMap$项对会话对象的弱引用。WeakHashMap通过静态强引用保持活动状态
- 对象只有在其弱引用被清除后才有资格进行终结(http://download.oracle.com/javase/6/docs/api/java/lang/ref/package-summary.html)
- 会话对象没有可以恢复它的终结器,即使它有,当对象仍在其他对象后面的未终结队列中时,也无法运行它
- 我的应用程序不使用幻影引用,幻影引用是对象符合最终确定条件后应该能够存在的唯一引用。即使我的应用程序确实使用了幻影参照,这些对象也不会公开它们对所持有对象的引用
- 弱参考仅是GC的指示。你没有确切的保证什么时候会被清除。我认为你在这里犯的错误就在这一部分:
来自终结器线程拥有的“未终结”链接列表的终结器引用。我的目标是第三行要完成
如果你正在谈论这个:
static private Finalizer unfinalized = null;
在Sun的Finalizer.java
(一个Finalizer
包含一个next
和prev
Finalizer
,因此对于那些在家玩的人来说是“链表”部分),那么这不是要确定的事情列表
Finalizer.add()
在对象不可访问的情况下,不会在终结过程中调用(我想您是这样假设的);相反,该方法是在对象创建时调用的(例如,在
期间,对于覆盖finalize()
的任何对象,由本机代码调用)
在next
链中出现终结器并不意味着它即将被终结;它是
static private ReferenceQueue queue
包含这样的对象。在链表中只意味着它有一个finalize()
方法
因此,您的第一点是一条红鲱鱼,第二点是保持项目可访问性的第二点,第三点是从第二点开始的(因为对象可访问时,WeakReference
不会被清除)
希望这有帮助!您可以再次使用计划完成的对象 我知道: 会话对象不存在 没有一个可以 复活它,即使它做到了 不可能在 对象仍处于未完成状态 在其他对象后面排队 但是,可能还有其他对象这样做(例如,对会话进行引用并使其自身重新定位)。无论哪种方式,都会显示该会话内容的终结器
注意:在清除幻影引用之前,对象将不可用于最终确定。(幻影引用最常用于调度死前清理操作,javadoc),pre(而不是像post一样的弱操作).您是否在会话对象仍然可访问的情况下完成了其中一个会话对象的最终确定?如果没有,我就不担心了。处于队列中并不一定意味着它将在强引用和/或弱引用仍然有效的情况下完成。什么机制会阻止最终确定器队列中的对象最终确定?objec如果ts不符合条件,则不应在此队列中。这在中进行了解释。“假设垃圾收集器在某个时间点确定某个对象是弱可访问的。此时它将自动清除对该对象的所有弱引用”即使对象本身没有错误的最终确定,也可以通过其他引用来恢复对象。