【问题标题】:Understanding the Reference Handler thread了解引用处理程序线程
【发布时间】:2011-10-05 08:39:08
【问题描述】:

我将继续深入了解 Java 线程。不幸的是,我的 Java 认证没有涵盖这部分,所以学习的唯一方法是发布一系列愚蠢的问题。经过这么多年的 Java 开发,我有时想知道我还有多少需要学习 :-)

我现在特别注意引用处理程序线程。

"Reference Handler" daemon prio=10 tid=0x02da3400 nid=0xb98 in Object.wait() [0x0302f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x1aac0320> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:485)
    at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)
    - locked <0x1aac0320> (a java.lang.ref.Reference$Lock)

下面是一些问题,其中一些我知道答案,但我没有发布它,因为我想听听其他人的意见:

  1. Reference Handler 线程应该做什么?
  2. 线程转储应该被认为是自下而上,为什么堆栈跟踪以locked开头,lock语句不应该至少在线程运行后出现?
  3. “本机方法”是什么意思?
  4. 为什么是“Unknown Source”,在这种情况下线程转储无法调用源代码?
  5. 最后waiting on和locked是一样的,为什么?

像往常一样,我恳请回答所有问题,以便我标记为已回答。

【问题讨论】:

    标签: java reference thread-dump


    【解决方案1】:
    1. 怀疑它会为 JVM 处理正在运行的终结器。这是一个实现细节,因此未在 JVM 规范中指定。
    2. 这仅表示java.lang.ref.Reference$Lock 被锁定在前面行中提到的方法中(即ReferenceHandler.run()
    3. “本机方法”仅表示该方法是在本机(即非 Java)代码中实现的(想想 JNI)。
    4. Unknown Source 仅表示.class 文件不包含任何源代码位置信息(至少对于这一特定点而言)。这可能发生在方法是合成方法(这里看起来不像),或者类是在没有调试信息的情况下编译的。
    5. 当线程等待某个对象时,它必须在调用跟踪的某个时间点锁定了该对象,所以你不能 em> 确实有一个waiting on 没有对应的locked

    【讨论】:

    • 嗯...关于第 5 点,这是有道理的,我们可以说当“等待”语句出现时,然后在堆栈跟踪中总是出现具有相同地址的“锁”吗?
    • 好吧,如果您能详细解释问题 1,我可以将整个问题标记为已解决 :-)
    【解决方案2】:

    1) 终结器线程调用终结器方法。 参考线程具有类似的目的。

    http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Core/lang/java/lang/ref/Reference.java.htm

    OpenJDK 源声明它是一个

    高优先级线程将待处理的引用排入队列

    GC 创建一个需要处理的引用的简单链表,该线程快速将它们添加到适当的队列中。这分两个阶段完成的原因是 GC 除了找到引用之外什么都不做,这个线程调用处理这些引用的代码,例如调用 Cleaners,并通知 ReferenceQueue 监听器。

    2) 在进入同步方法之前,会为其获取锁。

    3-5) 由 Joachim 介绍;)

    【讨论】:

    • 太棒了。你能解释一下待定引用是什么意思吗?
    • @JavaTechnical 这些是对需要在下一次 GC 上清理之前调用 finalize() 的对象的引用。
    • 谢谢。这意味着,finalize() 是否检查它们是否需要被释放?这是通过检查是否有任何引用指向该对象来完成的?我说的对吗?
    • 一个对象在没有强引用时可以被清理。如果finalize() 被覆盖,则调用它,即使它被空方法覆盖。
    • 我有一个问题,如果一个 1GB 文件映射到 directbytebuffer,当我明确调用 clean 时,这将“阻塞引用处理程序线程”(根据docjar.com/docs/api/sun/misc/Cleaner.html),这会有性能影响(或阻塞),当另一个线程正在创建对象 bdefore clean 完成?
    【解决方案3】:

    哇,对我来说太深了。我只能回答你的一两个问题。

    “本机方法”仅表示该方法的实现在某个本机(即 C 或 C++)库中。一旦调用堆栈“变为原生”,JVM 就无法再对其进行监控。它无法提供额外的堆栈信息。

    “未知来源”可能意味着代码是在打开优化和关闭调试信息的情况下编译的(-g 标志?)。这消除了 .class 文件中的文件/行信息。

    【讨论】:

    • 3 和 4 的答案很好,不幸的是我需要将它们都标记为已回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多