java运行时创建或修改类-JavaAgent

Javassist:使用-javaagent方式实现修改方法内容(打包和非打包方式执行) 1. 声明 当前内容主要为使用Javassit+(-javaagent)方式实现修改方法体的内容(不修改源码的情况下) 当前内容参考:Javassit官方文档,和部分反编译 主要内容: 使用javassit修改某个类的某个方法,实现执行 打成jar包方式执行 pom依赖 <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> < 阅读详情

在运维监控系统开发过程中我们往往需要在特定的方法出入口进行记录日志、采集参数,甚至在特定场景下需要对方法的出入参数或者整个方法逻辑进行重写。目前市面上开源的APM系统主要有CAT、Zipkin、Pinpoint、SkyWalking,大都是参考Google的Dapper实现的。个人在项目中主要使用skywallking,在java、golang等多语言中有过实践,所以这里主要记录自己在java项目中使用skywallking的一些心得和笔记。

Skywalking介绍

Skywalking是一个国产的开源框架,2015年有吴晟个人开源,2017年加入Apache孵化器,国人开源的产品,主要开发人员来自于华为,2019年4月17日Apache董事会批准SkyWalking成为顶级项目,支持Java、.Net、NodeJs等探针,数据存储支持Mysql、Elasticsearch等,跟Pinpoint一样采用字节码注入的方式实现代码的无侵入,探针采集数据粒度粗,但性能表现优秀,且对云原生支持,目前增长势头强劲,社区活跃。

Skywalking是分布式系统的应用程序性能监视工具,专为微服务,云原生架构和基于容器(Docker,K8S,Mesos)架构而设计,它是一款优秀的APM(Application Performance Management)工具,包括了分布式追踪,性能指标分析和服务依赖分析等。

Skywallking通过集成开源的Bytebuddy来实现对特定类的方法、字段等实现字节码修改,从而达到上下文传递、数据采集等功能,其底层是基于Java Instrumentation(jdk1.5+)技术实现。

Instrumentation介绍

从 JDK5 版本开始引入了java.lang.instrument 包,可以通过 addTransformer 方法设置一个 ClassFileTransformer,通过ClassFileTransformer 来实现类的字节码修改。

JDK 1.5 支持静态 Instrumentation,在 JVM 启动的时候通过 -javaagent:xxxx.jar的方式加载一个agent,该jar包含MANIFEST.MF 文件同时在里面指定代理类(Premain-class属性)和一个premain静态方法。JVM 启动时先执行代理类的 premain 方法完成transformer的注册,再执行 Java 程序本身的 main 方法运行程序。

JDK 1.6 开始支持更加强大的动态 Instrument,在JVM 启动后通过 Attach API 远程加载一个agent,和javaagent一样该jar需要包含MANIFEST.MF同时在里面制定代理类(Agent-class属性)和一个agentmain静态方法。JVM Attach成功后会通过进程间通信让目标jvm加载agent并且执行agentmain方法完成transformer的注册。

主要接口说明

/**
 * 为 Instrumentation 注册一个类文件转换器,可以修改读取类文件字节码
 */
void addTransformer(ClassFileTransformer transformer);

/**
 * 为 Instrumentation 注册一个类文件转换器,可以修改读取类文件字节码, 并指定是否支持重复转换
 */
void addTransformer(ClassFileTransformer transformer, boolean canRetransform);

/**
 * 为 Instrumentation 移除一个类文件转换器
 */
boolean removeTransformer(ClassFileTransformer transformer);

/**
 * 重复进行类文件转,修改读取类文件字节码
 */
void retransformClasses(Class<?>... classes) throws UnmodifiableClassException;

/**
 * 重新定义类信息
 */
void redefineClasses(ClassDefinition... definitions) throws  ClassNotFoundException, UnmodifiableClassException;

/**
 * 将jar包加入bootstrapClassLoader扫描范围,常用语加载外部jar
 */
void appendToBootstrapClassLoaderSearch(JarFile jarfile);

/**
 * 将jar包加入AppClassLoader扫描范围,常用于加载外部jar
 */
void appendToSystemClassLoaderSearch(JarFile jarfile);

javaagent方式修改类

// Demo.class 需要运行的java文件
public class Demo {
    public static void main(String[] args) {
        new Demo().hello();
    }
    public void hello() {
        helloBob();
        helloArno();
    }

    public void helloBob() {
    }

    public void helloArno() {
    }
}

// demoAgent.jar,包含DemoAgent代理类、MANIFEST.MF文件
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.commons.AdviceAdapter;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;

import static jdk.internal.org.objectweb.asm.Opcodes.V1_8;

/**
 * DemoAagent
 */
public class DemoAgent {

    public static void premain(String agentArgs, Instrumentation instrumentation) {
        instrumentation.addTransformer(new DemoClassFileTransformer());
    }

    public static class DemoMethodAdapter extends AdviceAdapter {
        private final String methodName;

        protected DemoMethodAdapter(int api, MethodVisitor mv, int access, String name, String desc) {
            super(api, mv, access, name, desc);
            methodName = name;
        }

        @Override
        protected void onMethodEnter() {
            super.onMethodEnter();
            // 改写方法,在这里输出"hello xxxx"
            mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
            mv.visitLdcInsn("hello " + methodName);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        }

        @Override
        protected void onMethodExit(int opcode) {
            super.onMethodExit(opcode);
        }
    }

    public static class DemoClassVisitor extends ClassVisitor {

        public DemoClassVisitor(ClassVisitor classVisitor) {
            super(V1_8, classVisitor);
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
            MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
            if (name.equalsIgnoreCase("helloBob") || name.equalsIgnoreCase("helloArno")) {
                return new DemoMethodAdapter(V1_8, mv, access, name, descriptor);
            }
            return mv;
        }
    }

    /**
     * 自定义ClassFileTransformer
     */
    public static class DemoClassFileTransformer implements ClassFileTransformer {
        @Override
        public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
            // TODO 对字节码进行修改; 原始字节码为 classfileBuffer;
            // 可以使用ASM、Javassist等字节码操作框架进行字节码修改操作, 这里使用jdk自带asm示例
            if (!"Demo".equals(className)) return classfileBuffer;
            ClassReader cr = new ClassReader(classfileBuffer);
            ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
            ClassVisitor cv = new DemoClassVisitor(cw);
            cr.accept(cv, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
            return cw.toByteArray();
        }
    }
}

// 2. MANIFEST.MF内容示例
Manifest-Version: 1.0
Premain-Class: DemoAgent
Can-Redefine-Classes: true
Can-Retransform-Classes: true

// 3. 运行程序
java -javaagent:demoAgent.jar Demo

java attach方式修改类

// 相比agent方式有三个不同
// 1. 启动命令中不在需要javaagent参数
// 2. agent类中premain方法需要切换成agentmian
// 3. 需要在一个新的进程中执行attach动作

/**
 * DemoAagent
 */
public class DemoAgent {

    // 这里改成agentmain提供给attach的方式执行
    public static void agentmain(String agentArgs, Instrumentation instrumentation) {
        instrumentation.addTransformer(new DemoClassFileTransformer());
    }
    
    ...
}

// 启动新进程执行attach动作
import com.sun.tools.attach.VirtualMachine;

/**
 * AttachMain
 */
public class AttachMain {

    // 这里改成agentmain提供给attach的方式执行
    public static void main(String[]] args) {
        // 需要attach的目标java进程
        String pid = ""; 
        
        // attach目标jvm,通过 jvm_pidxxxx 文件进行进程间通信
        VirtualMachine vm = VirtualMachine.attach(pid);
        
        // 发送信号,让目标jvm加载该agent,并执行agentmain方法
        vm.loadAgent(new File("demoAgent.jar").getAbsolutePath());
        
        // agent加载成功后,当前进程退出attach
        vm.detach();
    }
}

ByteBuddy使用

ByteBuddy主要通过自定义一套ClassFileTransformer机制降低字节码修改门槛。

ByteBuddy会根据不同修改方式生成不同的ClassFileTransformer,然后注册到Instrumentation中达到动态修改字节码的目的,Instrumentation有两种方式获得:

第一种由应用自行实现代理类,在类中实现premain/agentmain方法,在这两个方法中完成ByteBuddy类转换器注册。

第二种通过ByteBuddyAgent.install()方法由ByteBuddy自动生成临时agent jar文件(保存在java.io.tmpdir目录)并返回instrumentation。

注意:ByteBuddy实现的Agent容易和其他应用出现冲突,所以在maven打包时可以通过maven-shade-plugin直接将ByteBuddy的依赖和应用打包在同一个jar中,并且对包路径进行重定义。

参考地址:https://javadoc.io/doc/net.bytebuddy/byte-buddy#

// 1. 自行实现Agent
public class DemoAgent {

    // javaagent 方式执行
    public static void premain(String agentArgs, Instrumentation instrumentation) {
        
    }
    
    // attach api方式执行
    public static void agentmain(String agentArgs, Instrumentation instrumentation) {
        
    }
    
    public static void initByteBuddy(String agentArgs, Instrumentation instrumentation) {
        // 这里实现ByteBuddy相关逻辑    
    }
}

// 2. 委托Bytebuddy生成
public class DemoAgent {

    // javaagent 方式执行
    public static void main(String[] args) {
        // 业务逻辑 ....
        
        // 初始化Bytebuddy
        Instrumentation instrumentation = ByteBuddyAgent.install();
        initByteBuddy(null, instrumentation);
                        
        // 业务逻辑.....        
    }
    
    public static void initByteBuddy(String agentArgs, Instrumentation instrumentation) {
        // 这里实现ByteBuddy相关逻辑    
    }
}

ByteBuddy使用示例

// Demo.class 需要运行的java文件
public class Demo {
    public void hello() {
        System.out.println("====我是原始方法====")
    }
}

// 2. DemoAgent.java agent文件
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.matcher.ElementMatchers;

import java.lang.instrument.Instrumentation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.Callable;

import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;

/**
 * DemoAagent
 */
public class DemoAgent {

    // javaagent 方式执行
    public static void main(String[] args) {
        // 业务逻辑 ....

        // 初始化Bytebuddy
        Instrumentation instrumentation = ByteBuddyAgent.install();
        initByteBuddy(null, instrumentation);

        // 业务逻辑.....
    }

    public static void initByteBuddy(String agentArgs, Instrumentation instrumentation) {
        AgentBuilder agentBuilder = new AgentBuilder.Default()
                .disableClassFormatChanges()
                // 设置需要忽略的类、方法等,支持多种ElementMatcher匹配模式
                .ignore(nameStartsWith("net.bytebuddy.").or(nameStartsWith("java.")))
                // 设置默认字节码修改策略,比如TypeStrategy、InjectionStrategy等
                .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
                .with(AgentBuilder.TypeStrategy.Default.REDEFINE)
                .with(AgentBuilder.InjectionStrategy.UsingUnsafe.INSTANCE)
                .with(AgentBuilder.RedefinitionStrategy.REDEFINITION);

        // 1. 通过Advice方式(ASM visitor方式),进行方法处理
        AgentBuilder.Transformer demoTransform =
                (builder, typeDescription, classLoader, module, protectionDomain) ->
                        builder.visit(Advice.to(DemoAdvice.class)
                                .on(ElementMatchers.isMethod().and(ElementMatchers.named("hello"))));
        agentBuilder = agentBuilder.type(ElementMatchers.named("Demo")).transform(demoTransform);


        // 2. 通过MethodDelegation(方法委托)方式,进行方法处理
        AgentBuilder.Transformer demoTransform1 =
                (builder, typeDescription, classLoader, module, protectionDomain) ->
                        builder.method((named("hello"))).intercept(MethodDelegation.to(DemoInterceptor.class));
        agentBuilder = agentBuilder.type(ElementMatchers.named("Demo")).transform(demoTransform1);

        // 将agentBuilder生成的ClassFileTransform注册到instrumentation中
        agentBuilder.installOn(instrumentation);
    }

    public static class DemoInterceptor {
        // 这里通过SuperCall注解将原方法调用注入
        public void hello(@SuperCall Callable<?> superCall) throws Exception {
            // 进入原方法前进行处理
            System.out.println("进入方法: hello");
            
            // 通过call方法对原方法发起调用
            superCall.call();
            
            // 原方法调用完成进行处理
            System.out.println("退出方法:hello");
        }
    }

    public static class DemoAdvice {
        /**
         * 方法进入时执行
         * @param method    方法
         */
        @Advice.OnMethodEnter
        public static void enter(@Advice.This Object obj, @Advice.Origin Method method) {
            System.out.println("进入方法: " + method.getName());
            System.out.println("方法参数: " + Arrays.toString(method.getParameterTypes()));
        }

        /**
         * 方法退出时执行
         * @param method    方法
         * @param throwable 异常信息
         */
        @Advice.OnMethodExit
        public static void exit(@Advice.Origin Method method, @Advice.Thrown Throwable throwable) {
            System.out.println("退出方法: " + method.getName());
            if (throwable != null) {
                System.out.println("方法异常: " + throwable.getClass().getName());
            }
        }
    }
}

ByteBuddy常用注解

注解用途示例
@Argument绑定参数,序号从0开始@Argument(0) Object param
@AllArguments绑定所有参数的数组@AllArguments Object[] params
@This当前被拦截的、动态生成的那个对象,注入后会使得原方法被调用@This Object obj
@DefaultCall调用默认方法而非super的方法​
@SuperCall用于调用父类版本的方法(原方法,不能修改参数)​
@RuntimeType可以用在返回值、参数上,提示ByteBuddy禁用严格的类型检查​
@Super当前被拦截的、动态生成的那个对象的父类对象​
@FieldValue注入被拦截对象的一个字段的值​
@Morph允许调用指定超类方法​

Maven打包插件示例

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.4.1</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <artifactSet>
                    <includes>
                        <!-- 需要处理的包路径 -->
                        <include>net.bytebuddy:byte-buddy:jar:</include>
                        <include>net.bytebuddy:byte-buddy-agent:jar:</include>
                    </includes>
                </artifactSet>
                <relocations>
                    <!-- 重新定义包路径, 对net.bytebuddy的包路径重定义为shaded.net.bytebuddy -->
                    <relocation>
                        <pattern>net.bytebuddy</pattern>
                        <shadedPattern>shaded.net.bytebuddy</shadedPattern>
                    </relocation>
                    <relocation>
                        <!-- 建议agent所在的包也要shade -->
                        <pattern>demo.agent</pattern>
                        <shadedPattern>shaded.demo.agent</shadedPattern>
                    </relocation>
                </relocations>
            </configuration>
        </execution>
    </executions>
</plugin>

​

解析 Sermant 热插拔能力:服务运行时动态挂载 JavaAgent 和插件 Sermant 是基于 Java 字节码增强技术的无代理服务网格,其利用 Java 字节码增强技术,为宿主应用程序提供服务治理功能,以解决大规模微服务场景中的服务治理问题,通过 Java 字节码增强技术,可以非侵入的提供服务治理能力。在以往版本中,Sermant 通过配置 - javaagent 指令在微服务启动时接入服务治理能力,当需要接入及卸载 Sermant 时都需要通过重新启动微服务来完成。 阅读详情

相关推荐

Flink任务运行时如何使用JavaAgent修改类字节码

有时候,在 Flink 任务运行时修改类的字节码可以为我们提供一些额外的功能,例如性能监控、动态代理等。JavaAgent 是 Java 虚拟机 (JVM) 提供的一个特性,它允许我们在类加载时修改类的字节码。通过上述步骤,我们成功地在 Flink 任务的运行时使用 JavaAgent 修改了类的字节码。在实际应用中,你可以根据需要修改目标类的字节码,实现各种功能,如性能监控、动态代理等。需要注意的是,JavaAgent 对于类的修改是全局生效的,意味着所有加载的类都会受到影响。在上面的命令中,我们通过。

BugCrusher的博客 310

java pre main_JavaAgent学习之旅(一|静态的premainDemo实例)

一:什么是JavaAgentJavaAgent顾名思义就是Java探针技术,我理解的是,通过一个JavaAgent探针类,可以在java虚拟机启动之前,或者运行的时候植入这个探针类,对jvm做一些特别的操作,如动态改变字节码文件这种,要想植入,肯定是通过jvm参数来搞了使用JavaAgent的技术的项目我目前知道的是SkyWalking,dubbo用没用我没印象了二:JavaAgent在JVM运行...

weixin_42394054的博客 256

【Flink】Flink任务如何在运行的时候使用javaagent修改类字节码

在【javassist】使用javassist修改kafka源码AbstractCoordinator类这个文章中,我们学到了在javaweb中,实现了修改kafka的运行时代码。这一章我们将把这个应用到flink集群上。这里我们先把包放到如下目录然后修改启动任务的脚本提交的命令如下这里我们将我们的参数从传入到flink集群了。提交命令的本地日志可以看到我们的打印如下然后在远程可以yarn日志也能看到加载了我们的日志然后提交任务成功后,可以看到如下打印的日志。

九师兄 509

JAVA进阶之Agent

1、什么是 Java Agent 笼统地来讲,Java Agent 是一个统称,该功能是 Java 虚拟机提供的一整套后门,通过这套后门可以对虚拟机方方面面进行监控与分析,甚至干预虚拟机的运行。 Java Agent 又叫做 Java 探针,是在 JDK1.5 引入的一种可以动态修改 Java 字节码的技术。Java 类编译之后形成字节码被 JVM 执行,在 JVM 在执行这些字节码之前获取这些字节码信息,并且通过字节码转换器对这些字节码进行修改,来完成一些额外的功能。 2、Instrumenta

Purpletaro的专栏 2657

【SOC估算】基于EKF与神经网络融合的锂电池SOC高精度估计及Matlab实现

本文探讨了基于EKF与神经网络融合的锂电池SOC高精度估计方法。通过结合扩展卡尔曼滤波(EKF)的模型驱动优势和神经网络的数据驱动学习能力,实现了对电池荷电状态(SOC)的精准预测。Matlab仿真验证了该混合算法在各种工况下均能显著降低估计误差,提升电池管理系统性能。

play7的博客 696

避坑指南:时间序列互相关分析(CCF)常见的5个误用场景

本文详细解析了时间序列互相关分析(CCF)中常见的5个误用场景,包括忽视平稳性检验、混淆同期相关与因果关联、误读滞后阶数、忽略自相关干扰以及样本量不足等问题。通过实际案例和技术建议,帮助数据分析师避免这些陷阱,确保CCF分析的准确性和可靠性。

weixin_29064009的博客 428

Java Agent原理及实现

Java Agent作为一个非常强大的工具,可以用于应用服务器的诊断和分析工具、AOP、调试器等多种应用场景,而开发者也可以根据自己的业务需求来实现各种各样的agent代码来实现扩展或者监控自己的应用程序。Java Agent是Java SE 5.0版本引入的一个新特性,它可以在Java虚拟机(JVM)启动前或者在运行时动态地读取一些class文件,并在内存中修改后替换原始的class文件,从而在不改变原有代码的情况下增强或者监视应用程序的运行。这样就能在控制台输出程序中每个方法的执行时间了。

Dc253061007的博客 596

Qwen 三代进化全景对比:从 Qwen2.5 到 Qwen3 再到 Qwen3.5

本文对比了阿里巴巴通义千问三代大模型(Qwen2.5、Qwen3、Qwen3.5)的技术演进。18个月内,模型在架构、训练数据和能力上实现显著突破:从纯稠密结构(Qwen2.5)发展为混合注意力架构(Qwen3.5),支持语言从29种扩展至201种,并实现原生多模态融合。关键进展包括引入MoE架构、Gated DeltaNet混合注意力机制(计算效率提升10倍)、以及从独立模态到早期视觉语言联合训练的转变。模型阵容从7个通用尺寸发展为8+个混合架构,最大参数量达397B,上下文窗口扩展至256K(托管版1M

m0_47999117的博客 1万+

Java探针--javaagent--使用/实例

本文用示例介绍javaagent的用法。

IT利刃出鞘的博客 2万+

VirusTotal API密钥获取与Python实战:从注册到自动化威胁分析

在网络安全和自动化运维领域,API(应用程序编程接口)是实现系统间数据交互与功能集成的核心技术。其工作原理是通过预定义的协议和端点,允许程序化访问特定服务的数据与功能。对于安全工程师和威胁分析师而言,API的价值在于能够将手动、重复的安全操作(如文件扫描、情报查询)转化为自动化工作流,从而极大提升威胁检测与响应的效率。一个典型的应用场景是集成第三方威胁情报平台,以实现对可疑文件、URL或哈希值的批量与实时分析。本文聚焦于全球知名的威胁情报服务VirusTotal,详细解析其API密钥的注册流程、安全配置要点

weixin_28707739的博客 421

RK3576平台部署NanoTrack:边缘AI视觉跟踪实战指南

边缘AI部署是将深度学习模型在资源受限的嵌入式设备上高效运行的关键技术,其核心在于模型压缩、硬件适配与软件栈优化。通过INT8量化、算子融合与内存优化等原理,能显著降低模型计算量与内存占用,从而在嵌入式NPU上实现实时推理。这项技术的价值在于为安防监控、无人机视觉、工业检测等场景提供低功耗、高响应的智能感知能力。以瑞芯微RK3576平台部署轻量级视觉跟踪模型NanoTrack为例,其过程涉及模型结构分析、RKNN工具链转换、C++推理程序开发及多线程性能优化,完整展现了从算法到产品的工程化路径,为开发者提供

weixin_31887307的博客 427

Java:javaagent

不同于于我们之前使用-Djava.library.path 指定其它的非Java类包用于实现JNIjavaagent本身就是命令的一个选项,用于Java类在加载前,做一些不可告人的事情cuiyaonan2000@163.com,这里所说的不可告人的事情其实就是:字节码插桩字节码插桩 听起来似乎很高大上的样子,实际上就是在Java应用启动加载类前通过某种机制在执行的字节码实现嵌入代码片段或者修改字节码的操作。...

难得糊涂 1736

虚拟电厂功率预测最佳实践白皮书

虚拟电厂(VPP)通过聚合分散的可再生能源资源,为电网提供可观测、可调度和可交易的解决方案。本文提出了一套功率预测方法论,并给出LSTM实现脚本,涵盖资源接入、数据治理、预测模型设计及市场交易闭环。针对风-光-储-负荷混合场景,该方法论强调轻量化部署和滚动优化,可有效提升预测精度和调度收益。未来研究将融合深度气象预报和强化学习,进一步优化VPP的协同调度能力。

专注AI大模型,软件混淆,授权 377

javaagent 运行动态修改代码

#render_0_1560413801-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#render_0_1560413801-svg .error-icon{fill:#552222;}#render_...

weixin_40539903的博客 433

【YOLOv8科研级创新】集成HS-FPN特征融合网络,让Neck模块在参数量锐减100W的同时精度跃升

打开确保模型解析器能识别HS_FPN模块。通过将HS-FPN集成到YOLOv8中,我们实现了一个“轻量级多尺度特征融合+精准检测”的目标检测模型。这个改进不仅在工程上能提升多尺度、细粒度场景的检测效果并降低部署成本,更在科研上提供了“选择性轻量级特征融合”的创新思路——这种思路可以延伸到其他检测网络(如Faster R-CNN、SSD)的Neck模块改进中,帮你在论文中打造独特的研究点。

m0_64661770的博客 138

材料仿真软件:LAMMPS_(8).温度和压力控制

在 LAMMPS 中,温度和压力的控制是通过多种恒温器和恒压器实现的。Nose-Hoover 恒温器和恒压器因其准确性和广泛适用性而被经常使用,而 Berendsen 恒温器和恒压器则因其计算效率高而适用于初步仿真或粗粒化模型。温度重标和压力重标方法虽然简单,但在某些情况下可以快速调整系统的温度和压力。通过选择合适的控制方法,可以根据具体的需求和系统特性来设计和运行分子动力学仿真,从而获得准确和可靠的结果。在实际应用中,建议先进行初步的仿真以确定合适的控制参数,然后再进行细致的仿真以验证结果的稳定性。

kkchenjj的博客 1695

什么是JavaAgent?

JavaAgent是在JDK5之后提供的新特性,故名思义也可以叫java代理.他不是应用程序中的一部分,instrument支持以Java代理的形式监控或重新定义运行中的服务.可以让我们在不修改程序代码的前提下通过Instrumentation API改变运行中的java程序. 代码演示 1、创建agent public class MyAgent { // premain是javaagent的入口 public static void premain(String agentArgs, Inst

qq_40708942的博客 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Javaagent使用指南

JVM启动前静态Instrument Javaagent是什么? Javaagent是java命令的一个参数。参数javaagent可以用于指定一个jar包,并且对该java包有2个要求: 这个jar包的MANIFEST.MF文件必须指定Premain-Class项。 Premain-Class指定的那个类必须实现premain()方法。 premain 方法,从字面上理解,就是运行在 main 函数之前的的类。当Java虚拟机启动时,在执行 main 函数之前,JVM会先运行-javaagent所指定

qq_31279701的博客 1万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

javaagent

javaagent Javaagent 是什么 Javaagent是java命令的一个参数。参数 javaagent 可以用于指定一个 jar 包,并且对该 java 包有2个要求: 这个 jar 包的 MANIFEST.MF 文件必须指定 Premain-Class 项。 Premain-Class 指定的那个类必须实现 premain() 方法。 premain 方法,从...

Frankltf的博客 483

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

javaagent统计目标方法运行时长

和操作库,用于在 Java 应用程序运行时创建和修改 Java 类,而无需编译器的帮助。除了 Java 类库附带的代码生成实用程序外,Byte Buddy 还允许创建任意类,并且不限于实现用于创建运行时代理的接口。对javaagent有一些了解之后,这次我们来展示javaagnet来统计目标方法的运行时长。2.创建你的运行时代码也是一个maven工程其他的工程也可以只需要能创建一个运行类即可。1.先创建一个javaagent的maven工程。最重要的一步配置运行类的javaagent参数。

sinat_42623729的博客 358

javaagent使用

是在JDK1.5以后引入的,它能够在不影响正常编译的情况下修改字节码,相当于是在main方法执行之前的拦截器,也叫premain,也就是会先执行premain方法然后再执行main方法。JDK 1.6后引入了agentmain模式,同样提供了一个agentmain方法,可以在main方法执行之后运行。方法将我们的jar包注入到对应的进程当中,然后被注入的进程就好调用jar包里的。可以看到,我们的agentmain方法的代理已经生效,其中。包含agentmain方法的类(类的全路径名)

zhangyifang_009的博客 1652

JavaAgent原理及实践

Java Agent是什么? java agent本质上可以理解为一个jar包插件,这个jar包通过JVMTI(JVM Tool Interface)完成加载,最终借助JPLISAgent(Java Programming Language Instrumentation Services Agent)完成对目标代码的修改。-javaagent是java命令的一个参数,应用启动是我们可以利用这个参数javaagent指定一个jar包,去实现我们想要它做的一些事情。 Java Agent能做什么? 可以

陈旭猿的博客 5591

JavaAgent技术原理

java agent本质上可以理解为一个插件,该插件就是一个精心提供的jar包,这个jar包通过JVMTI(JVM Tool Interface)完成加载,最终借助JPLISAgent(Java Programming Language Instrumentation Services Agent)完成对目标代码的修改。java agent技术的主要功能如下:可以在加载java文件之前做拦截把字节码做修改可以在运行期将已经加载的类的字节码做变更还有其他的一些小众的功能获取所有已经被加载过的类。

weixin_45653328的博客111 1933

Java探针-javaagent由浅入深(一)

前言(可忽略):近来因为公司要对我所负责的系统进行安全性的检测,项目需要引入VulHunter这个工具,引入的方式正是在Web容器上添加javaagent作为JVM参数,如:-javaagent:/home/haye/vulhunter.jar。这种引入对我的项目代码本身可以说是零侵入,但却实实在在的扫描到了项目存在的漏洞,对此甚为好奇,遂决定研究下javaagent的用法。 javaagent...

Quarrie的博客 3160

如何使用 Java Agent 在运行时修改 Java 类(以魔改 Jenkins 为例)

遇到问题 起因 深夜更新 Jenkins 插件的时候,遇到了一个问题:插件下载速度太慢了,并且有大概率失败。 因此我研究了一下 Jenkins 的插件升级机制,研究是否可以使用镜像站点加速。 初步研究 Jenkins 的 升级信息(包含本体和插件)来自于 http://mirrors.jenkins-ci.org/updates/update-center.json 这个 URL。 这个 JSON 文件描述了所有可用插件的 版本信息 和 下载地址,并且 Jenkins 在 插件中心 的 高级 选项卡里提供了

无限进步 2979

javassist 运行时动态修改代码

遇到一个有意思的任务:在运行时修改 class 行为. 顺理成章,把目光移到了 javassist上. javassist是一个java class 处理工具,常用于实现动态代理.常用来在各种框架里实现代理功能. 优点: 0 操作class的能力 1 可以运行时修改class文件 2 广...

chunluozi1278的博客 2264
上一篇: java类加载器挖坑记
下一篇: java运行时创建或修改类-JavaCompiler
QuietJiang
博客等级 码龄17年 0粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QuietJiang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值