javaAgent 参数

 

-javaagent 这个JVM参数是JDK 5引进的.

java -help的帮助里面写道:

-javaagent:<jarpath>[=<options>]
load Java programming language agent, see java.lang.instrument

JDK 工具文档里面,并没有很详细的说明。

1. 代理 (agent) 是在你的main方法前的一个拦截器 (interceptor),也就是在main方法执行之前,执行agent的代码。

agent的代码与你的main方法在同一个JVM中运行,并被同一个system classloader装载,被同一的安全策略 (security policy) 和上下文 (context) 所管理。

叫代理(agent)这个名字有点误导的成分,它与我们一般理解的代理不大一样。java agent使用起来比较简单。

怎样写一个java agent? 只需要实现premain这个方法

public static void premain(String agentArgs, Instrumentation inst)

JDK 6 中如果找不到上面的这种premain的定义,还会尝试调用下面的这种premain定义:

public static void premain(String agentArgs)

2. Agent 类必须打成jar包,然后里面的 META-INF/MAINIFEST.MF 必须包含 Premain-Class这个属性。

下面是一个MANIFEST.MF的例子:

Manifest-Version: 1.0
Premain-Class:MyAgent1
Created-By:1.6.0_06

然后把MANIFEST.MF 加入到你的jar包中。

3. 所有的这些Agent的jar包,都会自动加入到程序的classpath中。所以不需要手动把他们添加到classpath。
除非你想指定classpath的顺序。

4. 一个java程序中-javaagent这个参数的个数是没有限制的,所以可以添加任意多个java agent。

所有的java agent会按照你定义的顺序执行。
例如:

 java -javaagent:MyAgent1.jar -javaagent:MyAgent2.jar -jar MyProgram.jar

假设MyProgram.jar里面的main函数在MyProgram中。

MyAgent1.jar, MyAgent2.jar, 这2个jar包中实现了premain的类分别是MyAgent1, MyAgent2
程序执行的顺序将会是

MyAgent1.premain -> MyAgent2.premain -> MyProgram.main

5. 另外,放在main函数之后的premain是不会被执行的

例如

java -javaagent:MyAgent1.jar  -jar MyProgram.jar -javaagent:MyAgent2.jar

MyAgent2 和MyAgent3 都放在了MyProgram.jar后面,所以MyAgent2的premain都不会被执行,

所以执行的结果将是

MyAgent1.premain -> MyProgram.main

6. 每一个java agent 都可以接收一个字符串类型的参数,也就是premain中的agentArgs,这个agentArgs是通过java option中定义的。
如:

java -javaagent:MyAgent2.jar=thisIsAgentArgs -jar MyProgram.jar

MyAgent2中premain接收到的agentArgs的值将是”thisIsAgentArgs” (不包括双引号)

7. 参数中的Instrumentation:

通过参数中的Instrumentation inst,添加自己定义的ClassFileTransformer,来改变class文件。

8. 通过java agent就可以不用修改原有的java程序代码,通过agent的形式来修改或者增强程序了,或者做热启动等等。

9. JDK 6 中还增加了agentmain,agentmain可以在JVM运行过程中做一些事情,这个迟点再研究一下。

上面我写的例子可以在我的skydrive上面下载到:点击下载例子

参考:

http://download-llnw.oracle.com/javase/1.5.0/docs/api/java/lang/instrument/package-summary.html

http://download.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html

http://javahowto.blogspot.com/2006/07/javaagent-option.html

<think>嗯,用户想了解JVM-javaagent参数。首先,我需要回忆一下这个参数的作用。记得它是用来在JVM启动时加载Java代理的,代理可以用于监控、性能分析或者修改字节码。那Java代理具体是怎么工作的呢?应该涉及到Instrumentation API,还有premain方法。 然后,用户可能想知道如何实际使用这个参数。需要举例子,比如常见的应用场景,比如APM工具如SkyWalking或者字节码增强库Byte Buddy。可能还需要说明参数的具体格式,-javaagent后面跟着agent的jar路径,可能有多个参数的情况。 还要注意用户可能的疑问,比如多个代理时的执行顺序,或者与主程序的生命周期关系。需要解释代理是在main方法之前执行的,多个代理按指定顺序执行。另外,可能还要提到动态加载的情况,比如通过agentmain方法,但-javaagent是启动时加载的。 要确保回答结构清晰,分点说明,比如作用、工作原理、使用场景、示例代码结构、注意事项等。同时,检查是否遵循了系统级指令,比如数学公式的格式是否正确,虽然这个问题可能不太涉及数学内容,但如果有任何代码或路径中的变量,可能需要用$包裹,比如$JAR_PATH$之类的?不过可能不需要,这里主要是技术参数和代码示例。需要确保LaTeX语法正确,但这里可能用不上太多数学表达式。 可能还需要提到如何编写一个简单的Java代理,展示premain方法,以及MANIFEST.MF文件的配置。用户可能对实际实现步骤感兴趣,所以给出一个简单的示例会更好。比如创建一个类,包含premain方法,打包成jar并指定Premain-Class属性。 还要注意潜在的问题,比如在JDK的不同版本中是否有变化,或者安全权限的问题,比如需要设置某些权限策略文件。不过可能用户不需要太深入,但简要提到注意事项会有帮助。 总之,需要组织信息,确保用户能够逐步理解-javaagent的作用、如何配置、如何编写代理,以及常见的使用场景和需要注意的地方。保持回答结构清晰,分点说明,并给出实际示例来帮助理解。</think>JVM的 `-javaagent` 参数Java虚拟机提供的用于加载Java代理(Java Agent)的核心机制。以下是逐步解析: --- ### 一、核心作用 `-javaagent` 允许在JVM启动时加载一个 **Java代理程序**,主要用于: 1. **字节码增强**:在类加载时修改字节码(如AOP、性能监控) 2. **运行时监控**:收集JVM内部状态(内存、线程等) 3. **工具支持**:支撑IDE调试、性能分析工具(如Arthas、SkyWalking) --- ### 二、工作原理 1. **代理加载时机** 代理在 `main()` 方法执行**前**加载(通过 `premain` 方法),确保在程序启动时完成初始化。 2. **Instrumentation API** 通过 `java.lang.instrument.Instrumentation` 接口实现类操作: ```java public static void premain(String args, Instrumentation inst) { inst.addTransformer(new ClassFileTransformer()); // 注册字节码转换器 } ``` 3. **动态加载机制** 部分代理支持在运行时通过 `agentmain` 方法动态附加(需配合 `Attach API` 使用)。 --- ### 三、使用方式 1. **基础语法** ```bash java -javaagent:<agent-jar-path>[=<options>] -jar main-app.jar ``` - 可指定多个代理(按声明顺序依次执行) - 示例:`-javaagent:/path/to/agent.jar=debug=true` 2. **代理JAR要求** - 必须包含 `MANIFEST.MF` 文件,声明 `Premain-Class` 属性: ``` Premain-Class: com.example.MyAgent Can-Redefine-Classes: true Can-Retransform-Classes: true ``` --- ### 四、典型应用场景 1. **APM工具** - SkyWalking、Pinpoint 通过代理实现链路追踪 2. **性能分析** - 使用 `-javaagent:/path/to/async-profiler.jar` 采集性能数据 3. **Mock测试** - 修改第三方库行为(如模拟数据库连接) 4. **字节码增强库** - Byte Buddy、ASM 结合代理实现动态代码生成 --- ### 五、代码示例 1. **简单代理实现** ```java public class SimpleAgent { public static void premain(String args, Instrumentation inst) { System.out.println("Agent loaded with args: " + args); inst.addTransformer((loader, className, classBeingRedefined, protectionDomain, classfileBuffer) -> { // 字节码处理逻辑 return classfileBuffer; }); } } ``` 2. **MANIFEST.MF配置** ``` Manifest-Version: 1.0 Premain-Class: SimpleAgent ``` --- ### 六、注意事项 1. **执行顺序** 多个 `-javaagent` 参数按命令行中的顺序依次加载。 2. **安全限制** 需配置安全策略文件(如访问敏感API时)。 3. **版本兼容性** 不同JDK版本的Instrumentation API可能存在差异。 --- 通过 `-javaagent` 参数,开发者可以实现对JVM的深度干预,这是构建高级监控、调试工具的核心技术基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值