美文网首页
【工作问题】jconsole不能连接本地idea程序

【工作问题】jconsole不能连接本地idea程序

作者: 静筱 | 来源:发表于2019-01-04 14:34 被阅读0次

    问题描述:

    本地idea里的一个简单java例子,debug停在图示语句,运行jconsole尝试连接该进程。反复提示连接失败


    image.png 屏幕快照 2019-01-03 下午3.33.01.png

    问题诊断:

    • 搜索关键词“idea jconsole 本地连接失败”,查到的都是说要在jvm参数里增加:
    -Djava.net.preferIPv4Stack=true 
    

    如下图所示增加后不生效:


    image.png
    • 尝试用jconsole连接idea的进程,可以成功:
    image.png

    抓出两个进程启动的参数分别如下:

    【可以连接】


    image.png

    【不能连接】


    image.png

    发现其中不能连接的启动参数中有
    -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:58329

    这是debug模式运行时开放的端口,用于和jvm通信,获取jvm运行状态中的必要信息。

    于是猜想,是否是debug模式不支持连接jconsole,随即将代码改成如下:

    public class ReferenceTest {
    
        public static void main(String[] args){
    
    
            String b = new String("test");
    
            while(true){
                System.out.println(b);
            }
        }
    }
    

    运行,再从jconsole连接,成功:

    image.png
    • 尝试把之前加的jvm参数都去掉,再执行,仍然可以连接成功。

    结论

    idea中debug模式运行停在断点时,jconsole不能连接该进程。与jvm参数之类的没有关系。
    以上jvm参数在jconsole连接远程虚拟机进程时需要确保设置,才能正常连接。
    com.sun.management.jmxremote.port=portNum

    深入探究

    • debug原理:
      本质上debug原理是通过一种方式把jvm运行时的状态(变量值,当前运行行号,异常信息等等)传递回IDE进行显示。这种方式不能污染jvm运行时的数据,也就是需要在运行中途停得下来,又不会影响其继续执行。可以类比成水流,jvm运行时就像是水一直在流,断点相当于在水流经的某一处放置档板,使其完全停在此处,一旦档板放开,水流继续正常流淌。

    具体的实现是基于Java对外提供的专门用于调度和监控虚拟机使用的API,也就是Java Platform Debugger Architecture(JPDA).

    关于JPDA需要知道的重点如下:

    1. JPDA包括三个层次,图示如下。


      image.png
    2. 通过JDI与被调试的虚拟机进程通信,底层是通过TCP socket方式实现的。

    更多详细说明,参考如下文档:
    https://yq.aliyun.com/articles/56?spm=5176.100238.yqhn2.7.NLnzoh

    • jconsole连接原理:

    底层通过jmx协议来连接、监控和管理虚拟机进程。

    jmx协议实现时可以支持多种底层网络协议如rmi,http等

    至此,还是没有想清楚 为什么idea中debug模式启动的进程不能被jconsole连接。

    进一步查看运行模式和debug模式启动进程的差别:
    运行模式:

    -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=56196:/Applications/IntelliJ IDEA.app/Contents/bin
    

    debug模式:

    -javaagent:/Users/mac/Library/Caches/IntelliJIdea2018.2/captureAgent/debugger-agent.jar=file:/private/var/folders/58/kbmn4r191jggdg23jnph_q4c0000gn/T/capture.props
    
    • -javaagent实际上是jvm提供的一个类似AOP的方式,允许程序运行之前,修改运行的字节码。就是在运行main函数之前,jvm会先调用javaagent里指定的一个类似interceptor的程序。相当于开了一个proxy或者是agent。

    关于javaagent的使用详见:
    https://www.cnblogs.com/aspirant/p/8796974.html

    这两种模式主要差别在于这个javaagent是不同的。

    未完待续:

    除了这个不同以外,未发现其他不同。
    而这个不同与jmx连接也没啥关系。
    暂时没有其他调查思路。

    相关文章

      网友评论

          本文标题:【工作问题】jconsole不能连接本地idea程序

          本文链接:https://www.haomeiwen.com/subject/lvgclqtx.html