当连接到具有许多线程的远程JVM(即通过TCPIP传输线程调试信息)时,Java的JDB(和Eclipse)会挂起

时间:2015-07-07 20:33:37

标签: java eclipse remote-debugging jvm-hotspot jdb

问题描述

大家好,

我今天遇到了对新服务器进行远程调试的问题,最初看起来好像Eclipse需要很长时间才能连接到远程JVM。然而,经过一些调查后,我意识到jdb遇到了类似的问题。有些挖掘出现了......

连接到远程JVM不是问题。两个调试器都会在几秒钟内正确建立套接字连接。 jdb甚至处理命令。但是,在远程调试器成功连接到它之后,Sun Java 1.7.0_60-b19 JVM在通过TCPIP在网络上发送其线程调试信息(JVMTI / JDWP)时似乎挂起(或传输速度非常慢)。

列出远程JVM的线程似乎是问题。 JDB的threads命令挂起或执行速度非常慢。远程JVM上的负载是合理的,并且没有设置任何断点。在这个JVM上同时执行许多线程(~2005个线程),并且可能存在一些WAN延迟,但仍然需要有一种方法可以成功使用远程调试器!

观察。我猜测这与JVM的Java调试线协议(JDWP)实现通过TCPIP进行的线程信息传输效率低有关,因为机器在广域网的另一端。但是 - Windows远程桌面连接到同一台机器是可以接受的快速和高性能。鉴于此,似乎必须等待45分钟的Eclipse或JDB在JVM上列出线程信息是不可接受的,可能是一个错误(或一个非常糟糕的实现功能)。

可能与?

有关
  1. http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6401245 - 这个 看起来它已经修复,不再是问题了。此外,JVM在Windows数据中心而不是Linux上运行。
  2. http://www.eclipsecon.org/2013/comment/reply/1153.html - 可能 解决方案,但需要SAP JVM?
  3. https://github.com/vpotapev/jbreakpoint - 开源jdb界面 但是没有解决Eclipse的问题。
  4. 问题。有没有人有任何想法如何使线程数据传输更高效,以便JVM可以有效地远程调试?这是JVM的Java调试线协议(JDWP)中的错误吗?

    问题详情

    Java版:

    C:\Users\Administrator>"C:\Program Files\Java\jdk1.7.0_60\bin\java" -version
    java version "1.7.0_60"
    Java(TM) SE Runtime Environment (build 1.7.0_60-b19)
    Java HotSpot(TM) 64-Bit Server VM (build 24.60-b09, mixed mode)
    

    Application Server。与Weblogic 10g一起发生。 IBM WebSphere 8.5也会发生这种情况

    Eclipse。当尝试使用线程信息填充Debug视图时,Eclipse远程调试会无限期挂起。

    JDB - 远程。当使用jdb命令列出线程时,Java的thread远程调试器会挂起超过10分钟。然后它非常缓慢地列出它们(每秒1个线程,将所有列出它们需要33分钟)。

    "C:\Program Files\Java\jdk1.7.0_60\bin\jdb.exe -connect com.sun.jdi.SocketAttach:hostname=xxx.yyy.com,port=7777
    Set uncaught java.lang.Throwable
    Set deferred uncaught java.lang.Throwable
    Initializing jdb ...
    > threads
    Group system: <<jdb hangs here trying to get thread information>>
    

    JDB - Local。当在JVM的本地计算机上运行时,Java jdb远程调试器在3秒内执行threads命令。

    "C:\Program Files\Java\jdk1.7.0_60\bin\jdb.exe -connect com.sun.jdi.SocketAttach:hostname=xxx.yyy.com,port=7777
    Set uncaught java.lang.Throwable
    Set deferred uncaught java.lang.Throwable
    Initializing jdb ...
    > threads
    Group system:
    > threads
    Group system:
      (java.lang.ref.Reference$ReferenceHandler)0x7484                                                                  Reference Handler
      (java.lang.ref.Finalizer$FinalizerThread)0x7485                                                                   Finalizer
      (java.lang.Thread)0x7486                                                                                          ...
    GC Daemon
      (java.lang.Thread)0x748b                                                                                          RMI RenewClean-
    ...
    >
    

1 个答案:

答案 0 :(得分:1)

经过一些调查和数据包嗅探后,似乎远程进程中有大量线程会导致调试数据包拥塞以及远程进程调试代理和远程调试器之间处理延迟的反馈循环。基本上,JVM调试代理不是为高延迟连接而设计的,也不是为远程调试大量线程而设计的。它也不会尝试压缩线程/堆栈/变量更新信息以降低调试器的传输时间。

我们的解决方案最终是为我们的产品添加了线程调试模式,减少了各种服务器线程池大小,然后调试突然在海外网络中再次响应。

未来对Java社区的建议是向Eclipse和Java调试代理添加线程过滤器功能,以便在发出每个代码步骤后,只将感兴趣的线程的信息传输到调试器。