JPDA 架构研究19 - JDI的连接模块

简介:

引入:

上文提到了JDI的Mirror机制,把整个目标虚拟机上的所有数据、类型、域、方法、事件、状态和资源,以及调试器发向目标虚拟机的事件请求等都映射成Mirror 对象。这里进一步讨论JDI的链接模块。


分析:

连接模块其主要目的是提供调试器(Debugger)到目标虚拟机(Target VM)之间的交互通道。

从连接的发起方来看:连接的发起方可以是调试器,也可以是目标虚拟机。

从连接的数量来看,一个调试器可以连接多个目标VM, 但是一个目标VM只可以连接一个调试器。


我们从调试器(Debugger)的角度,可以把连接分为主动连接和被动连接。


分类1:主动连接 (它表示调试器主动去连接Target VM)

又分两种情况:

a. 当Target VM还没启动时,则使用LaunchingConnector这种形式的连接器,它会启动目标VM并连接。

Step 1: 调试器调用 VirtualMachineManager 的 launchingConnectors()方法获取所有的LaunchingConnector的实例。

1
2
3
4
5
6
7
public  List<LaunchingConnector> launchingConnectors()
   {
     ArrayList list =  new  ArrayList( 2 );
     list.add( new  SocketLaunchingConnectorImpl( this ));
     list.add( new  SocketRawLaunchingConnectorImpl( this ));
     return  list;
   }


Step 2:根据传输方式或其他特征选择一个LaunchingConnector,调用其 launch() 方法启动并且连接目标虚拟机 。启动后,返回目标虚拟机的实例。

比如说,如果选用SocketLaunchingConnectorImpl,则它的launch()方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public  VirtualMachine launch(Map<String, ?  extends  Connector.Argument> connectionArgs)
     throws  IOException, IllegalConnectorArgumentsException, VMStartException
   {
     getConnectionArguments(connectionArgs);
 
     SocketListeningConnectorImpl listenConnector =  new  SocketListeningConnectorImpl(
       virtualMachineManager());
     Map args = listenConnector.defaultArguments();
     ((Connector.IntegerArgument)args.get( "timeout" )).setValue( 10000 );
     String address = listenConnector.startListening(args);
 
     String slash = System.getProperty( "file.separator" );
     String execString =  this .fHome + slash +  "bin"  + slash +  this .fLauncher;
 
     execString = execString +  " -Xdebug -Xnoagent -Djava.compiler=NONE" ;
     execString = execString +  " -Xrunjdwp:transport=dt_socket,address="  + address +  ",server=n,suspend="  + ( this .fSuspend ?  "y"  "n" );
 
     if  ( this .fOptions !=  null ) {
       execString = execString +  " "  this .fOptions;
     }
 
     execString = execString +  " "  this .fMain;
 
     String[] cmdLine = DebugPlugin.parseArguments(execString);
     Process proc = Runtime.getRuntime().exec(cmdLine);
     try
     {
       virtualMachine = (VirtualMachineImpl)listenConnector.accept(args);
     }
     catch  (InterruptedIOException localInterruptedIOException)
     {
       VirtualMachineImpl virtualMachine;
       proc.destroy();
       String message = NLS.bind(ConnectMessages.SocketLaunchingConnectorImpl_VM_did_not_connect_within_given_time___0__ms_1, 
         new  String[] { 
         ((Connector.IntegerArgument)args
         .get( "timeout" )).value() });
       throw  new  VMStartException(message, proc);
     }
     VirtualMachineImpl virtualMachine;
     virtualMachine.setLaunchedProcess(proc);
     return  virtualMachine;
   }


b.当Target VM已经启动时,则使用AttachingConnector这种形式的连接器,它会挂接到目标虚拟机上。

前提是,Target VM必须以以下方式启动  -agentlib:jdwp=transport=xxx,server=y 参数启动,并根据传输方式生成监听地址。

Step1:调试器启动,调用 VirtualMachineManager 的 attachingConnectors()  方法获取所有的AttachingConnector的实例。

1
2
3
4
5
  public  List<AttachingConnector> attachingConnectors()
   {
     ArrayList list =  new  ArrayList( 1 );
     list.add( new  SocketAttachingConnectorImpl( this ));
     return  list;


Step 2: 根据目标虚拟机采用的传输方式选择一个AttachingConnector,调用其 attach() 方法挂接到目标虚拟机上。完成连接后,返回目标虚拟机的实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  public  VirtualMachine attach(Map<String, ?  extends  Connector.Argument> connectionArgs)
     throws  IOException, IllegalConnectorArgumentsException
   {
     getConnectionArguments(connectionArgs);
     Connection connection =  null ;
     try  {
       connection = ((SocketTransportImpl) this .fTransport).attach( this .fHostname, 
         this .fPort,  this .fTimeout, 0L);
     catch  (IllegalArgumentException e) {
       List args =  new  ArrayList();
       args.add( "hostname" );
       args.add( "port" );
       throw  new  IllegalConnectorArgumentsException(e.getMessage(), args);
     }
     return  establishedConnection(connection);
   }


分类2:被动连接(它表示Debugger被动地等待或者监听由Target VM发起的连接)

前提是,Target VM必须以以下方式启动  -agentlib:jdwp=transport=xxx,address=yyy 参数启动,并根据传输方式生成监听地址。

Step 1:调试器通过 VirtualMachineManager 的 listeningConnectors() 方法获取所有的ListeningConnector实例。

1
2
3
4
5
6
  public  List<ListeningConnector> listeningConnectors()
   {
     ArrayList list =  new  ArrayList( 1 );
     list.add( new  SocketListeningConnectorImpl( this ));
     return  list;
   }


Step 2:调用ListeningConnector的 startListening() 方法让连接器进入监听状态。通过 accept() 方法通知连接器开始等待正确的入站链接,该方法将返回调试器正在监听的地址描述符;目标虚拟机会自动地 attach 到调试器上建立连接,然后返回目标虚拟机的实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  public  String startListening(Map<String, ?  extends  Connector.Argument> connectionArgs)
     throws  IOException, IllegalConnectorArgumentsException
   {
     getConnectionArguments(connectionArgs);
     String result =  null ;
     try  {
       result = ((SocketTransportImpl) this .fTransport).startListening( this .fPort);
     catch  (IllegalArgumentException localIllegalArgumentException) {
       throw  new  IllegalConnectorArgumentsException(
         ConnectMessages.SocketListeningConnectorImpl_ListeningConnector_Socket_Port, 
         "port" );
     }
     return  result;
   }




本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1588011,如需转载请自行联系原作者
目录
相关文章
|
2月前
|
机器学习/深度学习 安全 算法
十大主流联邦学习框架:技术特性、架构分析与对比研究
联邦学习(FL)是保障数据隐私的分布式模型训练关键技术。业界开发了多种开源和商业框架,如TensorFlow Federated、PySyft、NVFlare、FATE、Flower等,支持模型训练、数据安全、通信协议等功能。这些框架在灵活性、易用性、安全性和扩展性方面各有特色,适用于不同应用场景。选择合适的框架需综合考虑开源与商业、数据分区支持、安全性、易用性和技术生态集成等因素。联邦学习已在医疗、金融等领域广泛应用,选择适配具体需求的框架对实现最优模型性能至关重要。
607 79
十大主流联邦学习框架:技术特性、架构分析与对比研究
|
3月前
|
存储 JavaScript 开发工具
基于HarmonyOS 5.0(NEXT)与SpringCloud架构的跨平台应用开发与服务集成研究【实战】
本次的.HarmonyOS Next ,ArkTS语言,HarmonyOS的元服务和DevEco Studio 开发工具,为开发者提供了构建现代化、轻量化、高性能应用的便捷方式。这些技术和工具将帮助开发者更好地适应未来的智能设备和服务提供方式。
103 8
基于HarmonyOS 5.0(NEXT)与SpringCloud架构的跨平台应用开发与服务集成研究【实战】
|
3月前
|
机器学习/深度学习 算法 数据可视化
基于深度混合架构的智能量化交易系统研究: 融合SSDA与LSTM自编码器的特征提取与决策优化方法
本文探讨了在量化交易中结合时序特征和静态特征的混合建模方法。通过整合堆叠稀疏降噪自编码器(SSDA)和基于LSTM的自编码器(LSTM-AE),构建了一个能够全面捕捉市场动态特性的交易系统。SSDA通过降噪技术提取股票数据的鲁棒表示,LSTM-AE则专注于捕捉市场的时序依赖关系。系统采用A2C算法进行强化学习,通过多维度的奖励计算机制,实现了在可接受的风险水平下最大化收益的目标。实验结果显示,该系统在不同波动特征的股票上表现出差异化的适应能力,特别是在存在明确市场趋势的情况下,决策准确性较高。
105 5
基于深度混合架构的智能量化交易系统研究: 融合SSDA与LSTM自编码器的特征提取与决策优化方法
|
5月前
|
设计模式 前端开发 JavaScript
深入探索研究MVVM架构设计
【10月更文挑战第7天】
101 0
|
6月前
|
编解码 Linux 开发工具
Linux平台x86_64|aarch64架构RTMP推送|轻量级RTSP服务模块集成说明
支持x64_64架构、aarch64架构(需要glibc-2.21及以上版本的Linux系统, 需要libX11.so.6, 需要GLib–2.0, 需安装 libstdc++.so.6.0.21、GLIBCXX_3.4.21、 CXXABI_1.3.9)。
179 0
|
9月前
|
前端开发 JavaScript 架构师
Webpack模块联邦:微前端架构的新选择
Webpack的模块联邦是Webpack 5引入的革命性特性,革新了微前端架构。它允许独立的Web应用在运行时动态共享代码,无需传统打包过程。基本概念包括容器应用(负责加载协调)和远程应用(独立应用,可暴露模块)。实现步骤涉及容器和远程应用的`ModuleFederationPlugin`配置,以及在应用间导入和使用远程模块。模块联邦的优势在于独立开发、按需加载、版本管理和易于维护。通过实战案例展示了如何构建微前端应用,包括创建容器和远程应用,以及消费远程组件。高级用法涉及动态加载、路由集成、状态管理和错误处理。
159 3
|
9月前
|
监控 Java 关系型数据库
java版MES系统源码,后端采用 Spring Boot 多模块架构
MES系统采用Vue3的vue-element-plus-admin为后台,Spring Boot多模块架构,支持MySQL、Oracle等数据库,具备SaaS多租户功能。核心功能包括车间计划排程、工艺流程配置、生产质量管理、进度追踪、库存和排班管理等,全面覆盖生产运营关键环节。
154 0
java版MES系统源码,后端采用 Spring Boot 多模块架构
|
8月前
|
监控
交易平台---架构设计第一步拆分模块,拆分为7个模块
交易平台---架构设计第一步拆分模块,拆分为7个模块
|
3月前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
4月前
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
99 3

热门文章

最新文章