JPDA 架构研究13 - Agent利用环境指针访问VM(类管理篇)

简介:

2000元阿里云代金券免费领取,2核4G云服务器仅664元/3年,新老用户都有优惠,立即抢购>>>


阿里云采购季(云主机223元/3年)活动入口:请点击进入>>>,


阿里云学生服务器(9.5元/月)购买入口:请点击进入>>>,

引入:

上文中提到Agent如何利用环境指针访问VM的(Watch)功能,这里主要讲解如何去管理类的。


分类9:管理类

a.GetLoadedClasses. 获得虚拟机中所有被加载的类的数组。

jvmtiError
GetLoadedClasses(jvmtiEnv* env,
            jint* class_count_ptr,
              jclass** classes_ptr)

从返回值可以看出,class_count_ptr表示被加载的类的数量,classes_ptr表示类的数组列表。

注意,这里不包含内置类型对应的包装器类。比如说java.lang.Integer.TYPE就不包含在此列表中。


b.GetClassLoaderClasses.获取虚拟机中所有的Classloader所管理的类。

jvmtiError
GetClassLoaderClasses(jvmtiEnv* env,
            jobject initiating_loader,
            jint* class_count_ptr,
            jclass** classes_ptr)


c.GetClassSignature.获取某类的签名

jvmtiError
GetClassSignature(jvmtiEnv* env,
            jclass klass,
            char** signature_ptr,
            char** generic_ptr)

这里的签名是用的JNI类型签名方式,比如说java.util.List 的类签名是 "Ljava/util/List;"  而 int[] 的类签名是 "[I"


d.GetClassStatus.获取类状态

jvmtiError
GetClassStatus(jvmtiEnv* env,
            jclass klass,
            jint* status_ptr)

类的有如下状态,分别用状态标志位来表示:

JVMTI_CLASS_STATUS_VERIFIED 1 类的字节码已经被修改
JVMTI_CLASS_STATUS_PREPARED 2 类准备状态已经完成  
JVMTI_CLASS_STATUS_INITIALIZED 4 类初始化完毕,静态初始化块已运行 S
JVMTI_CLASS_STATUS_ERROR 8 类初始化错误,因此不可使用。  
JVMTI_CLASS_STATUS_ARRAY 16 类是个数组
JVMTI_CLASS_STATUS_PRIMITIVE 32  类是个原子类(比如 java.lang.Integer.TYPE).     


e.GetSourceFileName.获取指定类的源代码文件名

jvmtiError
GetSourceFileName(jvmtiEnv* env,
            jclass klass,
            char** source_name_ptr)


f.GetClassModifiers.获取类的访问修饰符

jvmtiError
GetClassModifiers(jvmtiEnv* env,
            jclass klass,
            jint* modifiers_ptr)

一般类的访问修饰符就是 public/private/protected ,另外还有final.

另外,如果类是原子类(比如java.lang.Integer.TYPE),则它的访问修饰符必定是public final.并且一定没有对应的interface.


g.GetClassMethods.获取类的方法列表。

jvmtiError
GetClassMethods(jvmtiEnv* env,
            jclass klass,
            jint* method_count_ptr,
            jmethodID** methods_ptr)

按照约定,分别返回方法数量以及方法的列表。注意,这个方法列表还包括构造器和静态初始块。


h.GetClassFields.获取类的字段列表。

jvmtiError
GetClassFields(jvmtiEnv* env,
            jclass klass,
            jint* field_count_ptr,
            jfieldID** fields_ptr)

注意,这个字段列表只包含直接声明的字段,不包含它从父类中继承过来的字段。字段的返回顺序精确的等同于在类文件中声明的顺序。


i.GetImplementedInterfaces.获取类所实现的接口

jvmtiError
GetImplementedInterfaces(jvmtiEnv* env,
            jclass klass,
            jint* interface_count_ptr,
            jclass** interfaces_ptr)

注意,对于类来说,这里只返回它直接implements XXX,XXX的接口。

对于接口来说,这里返回它 extends XXX的接口。


j.IsInterface.判断某类是否是一个接口

jvmtiError
IsInterface(jvmtiEnv* env,
            jclass klass,
            jboolean* is_interface_ptr)


k.IsArrayClass.判断某类是否是一个数组类

jvmtiError
IsArrayClass(jvmtiEnv* env,
            jclass klass,
            jboolean* is_array_class_ptr)


l.GetClassLoader.获取某类对应的类加载器的引用。

jvmtiError
GetClassLoader(jvmtiEnv* env,
            jclass klass,
            jobject* classloader_ptr)


m.GetSourceDebugExtension.获取类的debug扩展信息。

jvmtiError
GetSourceDebugExtension(jvmtiEnv* env,
            jclass klass,
            char** source_debug_extension_ptr)


n.RedefineClasses.重新定义一组类 (强大的热交换技术)

typedef struct {
    jclass klass;
    jint class_byte_count;
    const unsigned char* class_bytes;
} jvmtiClassDefinition;
jvmtiError
RedefineClasses(jvmtiEnv* env,
            jint class_count,
            const jvmtiClassDefinition* class_definitions)

这功能挺有趣,因为如果指定的字节码,则重新定义某类。所以该方法通过传入一组字节码来重新定义一组类。重新定义某类之后,对于该类会有如下一些改变:

(1).线程无需被挂起。

(2).类中的所有断点都被清除。

(3).所有属性都被更新。(注意,这里的属性是class对象的属性,不是类文件中的属性,那个叫字段field)

(4).类的已有的所有实例,其在堆上的ID都不受影响,其含有的字段值都不受影响。

另外,对于类的重新定义,也有些约束:

(1)重定义可以改变方法体,常量池,字段。

(2)重定义不可以添加/修改/删除任何类中的方法和字段。

(3)重定义不可以修改方法签名,改变访问修饰符和继承关系。





本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1587816,如需转载请自行联系原作者
目录
相关文章
|
15天前
|
人工智能 API 决策智能
【AI Agent系列】【MetaGPT多智能体学习】0. 环境准备 - 升级MetaGPT 0.7.2版本及遇到的坑
【AI Agent系列】【MetaGPT多智能体学习】0. 环境准备 - 升级MetaGPT 0.7.2版本及遇到的坑
22 0
|
23天前
|
消息中间件 存储 数据库
RabbitMQ入门指南(二):架构和管理控制台的使用
RabbitMQ是一个高效、可靠的开源消息队列系统,广泛用于软件开发、数据传输、微服务等领域。本文主要介绍了RabbitMQ架构和管理控制台的使用等内容。
46 0
RabbitMQ入门指南(二):架构和管理控制台的使用
|
2月前
|
程序员 Python
类的设计奥秘:从代码到架构的科普全解
类的设计奥秘:从代码到架构的科普全解
13 2
|
2月前
|
存储 消息中间件 算法
深度思考:架构师必须掌握的五大类架构设计风格
数据流风格注重数据在组件间的流动,适合处理大量数据。调用返回风格则强调函数或方法的调用与返回,过程清晰明了。独立构件风格让每个构件独立运作,通过接口交互,提升灵活性和可重用性。虚拟机风格则模拟完整系统,实现资源的高效利用。
深度思考:架构师必须掌握的五大类架构设计风格
|
2月前
|
消息中间件 存储 SQL
Flume【基础知识 01】简介 + 基本架构及核心概念 + 架构模式 + Agent内部原理 + 配置格式(一篇即可入门Flume)
【2月更文挑战第18天】Flume【基础知识 01】简介 + 基本架构及核心概念 + 架构模式 + Agent内部原理 + 配置格式(一篇即可入门Flume)
492 0
|
2月前
|
SQL NoSQL 数据库
深入浅出:微服务架构下的数据库事务管理
【2月更文挑战第12天】 在当今微服务架构日益流行的背景下,如何有效地管理跨服务的数据库事务成为了开发与维护中的一大挑战。本文旨在探讨微服务环境下数据库事务管理的关键技术和策略,包括但不限于分布式事务的基本概念、常见的解决方案(如两阶段提交、补偿事务等),以及这些方案在实际应用中的优缺点比较。通过深入浅出的方式,本文希望能够帮助读者更好地理解并应对微服务架构下的数据库事务管理问题,进而提升系统的稳定性和可靠性。
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
Transformer类架构的发展带动多模态融合
【1月更文挑战第21天】Transformer类架构的发展带动多模态融合
48 1
Transformer类架构的发展带动多模态融合
|
4月前
|
存储 Cloud Native 数据处理
Flink 2.0 状态管理存算分离架构演进
本文整理自阿里云智能 Flink 存储引擎团队负责人梅源在 Flink Forward Asia 2023 的分享,梅源结合阿里内部的实践,分享了状态管理的演进和 Flink 2.0 存算分离架构的选型。
856 1
Flink 2.0 状态管理存算分离架构演进
|
5月前
|
存储 前端开发
Flutter Provider状态管理---MVVM架构实战
Flutter Provider状态管理—MVVM架构实战 在Flutter中,状态管理是一个非常重要的概念。Flutter Provider是一种状态管理的解决方案,它提供了一种简单,灵活和高效的方法来管理Flutter应用程序中的状态。本文将详细介绍Flutter Provider的使用,以及如何在MVVM架构中使用它。
163 0
|
5月前
|
消息中间件 运维 前端开发
(云HIS)云医院管理系统源码 SaaS模式 B/S架构 基于云计算技术
v(云HIS)云医院管理系统源码 SaaS模式 B/S架构 基于云计算技术
73 0
http://www.vxiaotou.com