zoukankan      html  css  js  c++  java
  • arthas与jvm-sandbox

    arthas与jvm-sandbox是阿里开源的JVM工具,都能够attach到一个正在运行的Java进程中,可以查看运行时的一些信息,并且可以通过对字节码的修改,来实现一些高级功能。 
    arthas和jvm-sandbox之所以能实现这些功能,主要依赖的有Java agent和ASM字节码修改。
    1. java agent是Jdk1.5之后引入的技术,可以随Java进程一起启动,或者attach到一个已经运行的Java进程。 在attach到进程后,Java本身提供了一些类(Instrumentation), 可以获取到一些运行信息,并且也提供了一些方法,可以对字节码进行干预。
    2. ASM可以生成或者修改字节码, 配合Instrumentation的addTransformer()和retransformClasses()方法,可以完成对字节码的修改。 
     
    为了便于对着两个技术的理解,我这里简化了一下,实现了一个demo。 
    业务类:
    package com.demo;
    
    public class Service {
    public void dosome() {
    System.out.println(
    "do some..."); } }
    package com.demo;
    
    import java.lang.management.ManagementFactory;
    import java.util.Scanner;
    
    /**
     * Hello world!
     */
    public class App {
    
        public static void main(String[] args) {
    
            // 获取pid  供agent使用
            String name = ManagementFactory.getRuntimeMXBean().getName();
            String pid = name.split("@")[0];
            System.out.println("应用程序进程Id:" + pid);
    
            // 注意这里实例化,类加载一次, 之后没有再加载
            Service service = new Service();
    
            // 键盘上输入F值,模拟业务执行
            Scanner scanner = new Scanner(System.in);
            System.out.println("按 F 执行程序");
    
            while (true) {
                String cmd = scanner.nextLine();
                if ("f".equalsIgnoreCase(cmd)) {
                    service.dosome();
                }
            }
        }
    }

    代理类:

    package com.agent;
    
    import java.lang.instrument.Instrumentation;
    import java.lang.instrument.UnmodifiableClassException;
    
    /**
     * Hello world!
     */
    public class AgentLauncher {
    
        public static void premain(String featureString, Instrumentation inst) {
            System.out.println("pre main");
        }
    
        /**
         * 通过attach的方式
         */
        public static void agentmain(String featureString, Instrumentation inst) throws UnmodifiableClassException {
            System.out.println("agent!!! 增强业务方法");
            // 增强
            MyClassFileTransformer myClassFileTransformer = new MyClassFileTransformer();
            // 添加到Instrumentation
            inst.addTransformer(myClassFileTransformer, true);
    
            // 找到需要重新加载的类
            Class<?>[] loadeds = inst.getAllLoadedClasses();
            Class<?> targetClass = null;
            for (Class<?> loaded : loadeds) {
                if (loaded.getName().equals("com.demo.Service")) {
                    targetClass = loaded;
                }
            }
            // 重新加载类, 保证动态的增强类生效
            inst.retransformClasses(targetClass);
            System.out.println("增强完毕,请重新执行业务方法");
    
        }
    
    
    }

    最后是attach

    package com.attach;
    
    import com.sun.tools.attach.VirtualMachine;
    
    /**
     * Hello world!
     */
    public class App {
    
        public static void main(String[] args) throws Exception {
    
            String targetJvmPid = "912"; // 业务进程ID
            if (args != null) {
                if (args.length > 0) {
                    targetJvmPid = args[0];
                }
            }
    
            if (targetJvmPid != null) {
                VirtualMachine vmObj = null;
                try {
                    vmObj = VirtualMachine.attach(targetJvmPid);
                    if (vmObj != null) {
                        // 加载agent的jar包, 需要先在agent项目中执行 maven package命令生成
                        vmObj.loadAgent("D:\jar\agent-1.0-jar-with-dependencies.jar");
                    }
    
                } finally {
                    if (null != vmObj) {
                        vmObj.detach();
                    }
                }
            }
        }
    }

    最后整体的运行效果如下:

    第一个红框是业务类正常运行的结果

    第二个红框执行attach的效果

    第三个是重新运行业务代码的效果,可以看到方法在执行前后加了一个start和end.

    完整的代码参考:https://github.com/zhaoyb/java-agent

  • 相关阅读:
    ASP记数器
    Photoshop压缩png图片方法之一
    Drupal的高速缓存配置APC
    各种share button
    兼容iphone、ipad与PC平台的在线视频
    知识组织方法总结
    Virtuemart2 for joomla2.5
    joomla2.5 常用组件
    网上找来经过改良的多级联动下拉菜单
    joomla组件开发中的时区问题
  • 原文地址:https://www.cnblogs.com/beyondbit/p/15272819.html
Copyright © 2011-2022 走看看