javaagent使用

Java Agent是什么?

在这里插入图片描述

Java Agent是Java平台提供的一个强大工具,它可以在运行时修改或增强Java应用程序的行为。是在JDK1.5以后引入的,它能够在不影响正常编译的情况下修改字节码,相当于是在main方法执行之前的拦截器,也叫premain,也就是会先执行premain方法然后再执行main方法。
使用javaagent可以用于执行一个jar包,并且对这个java包有两个要求:

  • jar包的MANIFEST.MF文件必须指定Premain-Class项
  • Premain-Class指定的那个类必须实现premain()方法
    当程序启动的时候,JVM会首先检查-javaagent所指定的jar包内Premain-Class这个类中的premain方法。

Java Agent的使用场景

  • 代码注入增强:允许在程序运行时对字节码进行操作,可以实现功能的增强。
  • 性能监控调优:可以监控应用程序方法执行时间、调用次数,类加载的一些信息进行性能检测,以及对一些问题的定位分析,比如一些性能监控和诊断工具如Pinpoint、Skywalking、Zipkin、Arthas等。
  • 日志记录审计:Java Agent可以在方法执行前后记录方法的调用信息,包括方法名、参数、返回值等,动态记录应用程序的运行日志。

Java Agent的简单使用

1.基于 Instrumentation 接口和premain()方法实现

新建一个maven项目,添加maven-jar-plugin插件依赖,用于打包并生成MANIFREST.MF文件。

<build><finalName>agenttestone</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.2.0</version><configuration><archive><!--自动添加META-INF/MANIFEST.MF --><manifest><addClasspath>true</addClasspath></manifest><manifestEntries><!--permain方法所在类的完全限定名--><Premain-Class>com.yifanghub.agent.PremainTest</Premain-Class><Agent-Class>com.yifanghub.agent.PremainTest</Agent-Class><Can-Redefine-Classes>true</Can-Redefine-Classes><Can-Retransform-Classes>true</Can-Retransform-Classes></manifestEntries></archive></configuration></plugin></plugins></build>

其中manifestEntries配置了一些属性
<Premain-Class>包含premain方法的类(类的全路径名)
<Agent-Class>包含agentmain方法的类(类的全路径名)
<Can-Redefine-Classes>是否可以重定义此代理所需的类,默认为false
<Can-Retransform-Classes>是否可以重新转换此代理类所需的类,默认为false

新建premain方法测试类,其中premain方法,agentArgs可以通过命令行传入

package com.yifanghub.agent;
import java.lang.instrument.Instrumentation;public class PremainTest {public static void premain(String agentArgs, Instrumentation inst) {System.out.println("premain执行---->");System.out.println("Hello agent test,agentArgs="+agentArgs);}
}

新建main方法测试类(新建一个项目)

package com.yifanghub.agent;public class PremainAgent {public static void main(String[] args) {System.out.println("agent测试走起,main方法执行");}
}

执行main方法,打印如下:

agent测试走起,main方法执行

idea配置:编辑启动类->Add VMOptions

-javaagent:D:\javaagent-demo\javaagent-demo-1.0-SNAPSHOT.jar=123运行程序,打印如下:
premain执行---->
Hello agent test,agentArgs=123
agent测试走起,main方法执行

注意事项

  1. agent的方法名必须是premain,否则会报错。

  2. agent抛出异常,会导致主程序的启动失败。

  3. premain方法只允许以下两种定义方式

     1)public static void premain(String agentArgs, Instrumentation inst)2)public static void premain(String agentArgs)JVM 会优先加载带有Instrumentation参数的方法1,加载成功忽略 2,如果1 没有,加载 2 方法。
    

2.基于 Attach 接口和agentmain()方法实现

JDK 1.6后引入了agentmain模式,同样提供了一个agentmain方法,可以在main方法执行之后运行

public static void agentmain (String agentArgs, Instrumentation inst)
public static void agentmain (String agentArgs)

1)创建agentmian方法类

import java.lang.instrument.Instrumentation;public class AgentmainTest {public static void agentmain(String agentArgs, Instrumentation inst) {System.out.println("agentmain执行---->");System.out.println("Hello I am agentmain test,agentArgs="+agentArgs);}
}

将上面代码打包,名字为:javaagent-demo2-1.0-SNAPSHOT.jar

2)创建被注入的main方法测试类(新建一个项目),这里主要使用一个for循环打印,让程序处于一直运行状态

public class MainTest {public static void main(String[] args) {System.out.println("开始执行mian");for (int i = 1; i <= 100000; i++) {System.out.println("第 " + i+ " 次循环");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

3)创建attach项目,编写main方法
这里用到了com.sun.tools.attach 包下面的VirtualMachine工具类来实现,该类表示一个Java虚拟机对象,该类的一些接口如下:

  • list():获取当前所有JVM列表
  • attach():根据进程id,连接到jvm上
  • detach():断开连接
  • loadAgent():加载agent

如果idea里面不能导入VirtualMachine类,导入JDK里面lib下的tool.jar包即可
在这里插入图片描述
attach方法如下:

import com.sun.tools.attach.*;
import java.io.IOException;
import java.util.List;public class AgentDemo4Test {public static void main(String[] args) throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException {System.out.println("AgentDemo4Test");List<VirtualMachineDescriptor> list = VirtualMachine.list();for (VirtualMachineDescriptor vmd : list) {if(vmd.displayName().equals("agent.MainTest")){System.out.println(vmd.displayName());VirtualMachine vm = VirtualMachine.attach(vmd.id());vm.loadAgent("D:\\javaagent-demo2-1.0-SNAPSHOT.jar","123456");vm.detach();}}}
}

4)启动运行MainTest类(第2步打印for循环的程序),然后执行上面AgentDemo4Test类的main方法,输出如下:
在这里插入图片描述
可以看到,我们的agentmain方法的代理已经生效,其中attach方法可以连接到一个正在运行的Java进程当中,之后便可以通过loadAgent方法将我们的jar包注入到对应的进程当中,然后被注入的进程就好调用jar包里的agentmain方法。

注意事项

  • agentmain()​方法会在加载之时立即执行,如果agentmain执行失败或抛出异常,JVM 会忽略掉错误,不会影响到正在运行的程序。

参考:https://www.cnblogs.com/LittleHann/p/17462796.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/825937.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务架构中的业务模块的可扩展设计

目录 1. 概要设计 1.1 服务拆分与独立部署 1.1.1 精细化拆分 1.1.2 独立部署能力 1.2 接口设计与通信机制 1.2.1 标准化接口 1.2.2 轻量级通信 1.3 数据管理与一致性 1.3.1 分布式数据管理 1.3.2 数据分区与复制 1.4 负载均衡与集群化 1.4.1 负载均衡 1.4.2 集群化…

plugins:Swift-BigInt 计算 斐波那契数列

Swift-BigInt 是 Swift 5 的轻量级易于使用的任意精度算术库。 它支持大多数常见数学运算符的整数&#xff08;BInt&#xff09;和分数&#xff08;BDouble&#xff09;。 还实现了优化的数学函数&#xff0c;例如阶乘或gcd&#xff0c;并可通过 BIntMath 访问。 计算 斐波那契…

vue3第二十二节(defineOptions用途)

defineOptions() 3.3 版本以上才可以使用 引言&#xff1a; 在使用组件时候 默认情况下&#xff0c;父组件传递的&#xff0c;但没有被子组件解析为 props 的 attributes 绑定会被**“透传”**。这意味着当我们有 一个单根节点(多根节点的是无法透传的) 的子组件时&#xff0…

【面试经典 150 | 二分查找】在排序数组中查找元素的第一个和最后一个位置

文章目录 写在前面Tag题目来源题目解读方法一&#xff1a;二分查找方法二&#xff1a;使用库函数 知识回顾二分查找的三种写法与三个问题常用的二分库函数 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更……

二叉树的层次遍历(配图详解)

二叉树的层次遍历 层序遍历顾名思义就是一层一层的遍历的树中的所有结点。 typedef char EmpeType 在本篇文章中&#xff0c;将char类型使用EmpeType&#xff1b; typedef char EmpeType;创建一个结构体 typedef struct BiTNode {EmpeType data; //数据域struct BiTNode* …

SpringCloud中的nacos注册中心分析

一、概述 服务注册中心是整个微服务架构体系中的关键组件之一&#xff0c;它负责服务的注册、发现及管理。nacos可以作为注册中心使用&#xff0c;提供了一种简化微服务架构中服务发现&#xff0c;服务注册及健康检查的功能&#xff0c;可以方便地管理微服务的实例。 二、naco…

使用docker配置CCM-SLAM

一.Docker环境配置 1.拉取Docker镜像 sudo docker pull ubuntu:18.04拉取的为ununtu18版本镜像&#xff0c;环境十分干净&#xff0c;可以通过以下命令查看容器列表 sudo docker images 如果想删除多余的docker image&#xff0c;可以使用指令 sudo docker rmi -f <id&g…

微服务设计模式:构建现代分布式系统的蓝图

引言 随着软件开发的进步和需求的变化&#xff0c;微服务架构逐渐崭露头角&#xff0c;成为当今分布式系统设计的主流方式。这种架构方式的兴起并非偶然&#xff0c;它为企业提供了构建灵活、可扩展且高效的应用程序的方法。在这篇博客中&#xff0c;我们将深入探讨微服务架构…

“开关是灯的日出日落,日出日落是灯的开关”

C语言刷题 day01 本篇是C语言刷题大杂烩&#xff0c;收集了笔者遇到的认为有价值的题目&#xff0c;本篇会持续更新~~ day01 至少是其他数字两倍的最大数 题目原文&#xff1a; 题意解析&#xff1a; 请你找出数组中的最大元素并检查它是否 至少是数组中每个其他数字的两倍 …

符文协议的演变历程:从挑战到创新

在比特币网络长期面临的挑战中&#xff0c;与主流去中心化金融功能的兼容性一直是一大难题。相比之下&#xff0c;以太坊通过ERC-721和ERC-1155代币标准&#xff0c;为NFT和去中心化金融应用提供了支持&#xff0c;而比特币的应用范围却相对有限。然而&#xff0c;近年来&#…

蓝桥杯2024年第十五届省赛真题-爬山

贪心优先队列的题&#xff0c;贪心会漏一个情况&#xff0c;不知道怎么处理&#xff0c;这里直接打表了 2 1 1 48 49 答案是30&#xff0c;贪心是31 专有名词&#xff1a;hack-有新的测试点过不了 #include<bits/stdc.h> using namespace std; #define endl \n #define …

Jellyfin插件手动导入步骤

1、进入文件夹 cd /volume1/appdata/Jellyfin/data 2、备份原文件夹 cp -r plugins/ /volume1/Download/plugins 3、复制插件 cp -r /volume1/Download/plugins/ ./ 4、赋予权限 chmod 777 -R plugins/

取模学习之Image2Lcd

使用软件Image2Lcd V0.4 1.&#xff1a;打开图片&#xff0c;图片格式可选如下图&#xff0c;本文使用的.jpg格式 转换后数组例子&#xff08;数组头数据占前8字节&#xff09;&#xff1a; 2.&#xff1a;扫描模式 由第1个字节低四位配置 &#xff08;1&#xff09;水平扫描 …

动手学深度学习11 权重衰退

动手学深度学习11 权重衰退 1. 权重衰退2. 代码实现3. QA 视频&#xff1a; https://www.bilibili.com/video/BV1UK4y1o7dy/?spm_id_fromautoNext&vd_sourceeb04c9a33e87ceba9c9a2e5f09752ef8 电子书&#xff1a; ttps://zh-v2.d2l.ai/chapter_multilayer-perceptrons/wei…

【MySQL 数据宝典】【内存结构】- 004 自适应哈希索引

自适应哈希索引 https://developer.aliyun.com/article/1230086 什么是自适应哈希索引&#xff1f; 自适应哈希索引是MySQL InnoDB存储引擎中的一种索引结构&#xff0c;用于加速查询。它根据查询模式和数据分布动态地调整自身的大小&#xff0c;以提高性能。 上图就是通过…

Redis中的订阅发布和事务(一)

订阅发布 PUBSUB NUMSUB PUBSUB NUMSUB [channel-1 channel-2… channel-n]子命令接受任意多个频道作为输入参数&#xff0c;并返回这些频道的订阅者数量。 这个子命令是通过pubsub_channels字典中找到频道对应的订阅者链表&#xff0c;然后返回订阅者链表的长度来实现的(订阅…

Nuclei 减少漏报的使用小技巧

在最近工作的渗透测试项目中发现Nuclei存在一个问题&#xff0c;就是相同的网站连续扫描多次会出现漏报的情况&#xff0c;此前没有注意过这个情况&#xff0c;所以写篇文章记录一下。 在此之前我的常用命令都是一把梭&#xff0c;有就有没有就继续其他测试 $ nuclei -u htt…

代码随想录算法训练营第四十五天| 70. 爬楼梯 (进阶),322. 零钱兑换 ,279.完全平方数

题目与题解 70. 爬楼梯 &#xff08;进阶&#xff09; 题目链接&#xff1a;70. 爬楼梯 &#xff08;进阶&#xff09; 代码随想录题解&#xff1a;70. 爬楼梯 &#xff08;进阶&#xff09; 解题思路&#xff1a; 这道题要求每次可以爬1-m层的楼梯&#xff0c;最终爬到n&…

微服务架构中的业务数据可视化设计

目录 1.概要设计 1.1明确可视化目标 1.2数据整合与标准化 1.3选择合适的数据可视化工具 1.4设计可视化界面 1.5 实时更新与优化 2.技术实现 2.1数据采集与整合 2.2数据处理与转换 2.3数据存储 2.4 数据可视化 2.5 实时数据更新 2.6 安全性与权限控制 2.7 监控与日…

【ZZULIOJ】1072: 青蛙爬井(Java)

目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy 提示 code 题目描述 有一口深度为high米的水井&#xff0c;井底有一只青蛙&#xff0c;它每天白天能够沿井壁向上爬up米&#xff0c;夜里则顺井壁向下滑down米&#xff0c;若青蛙从某个早晨开始向外爬&#xff0c…