Java字节码4-使用Java-Agent实现一个JVM监控工具

一、概述
在前面几节当中,我们构造了多个Agent。Agent由于是在main方法之前执行,我们可以做很多事情。 
本节中,我们将使用Agent技术来监控应用程序的JVM内存和GC信息。

二、实现
1、修改pom.xml


    javassist
    javassist
    3.12.1.GA
    jar


    net.bytebuddy
    byte-buddy
    1.5.7


    net.bytebuddy
    byte-buddy-agent
    1.5.7


my-agent

   
        org.apache.maven.plugins
        maven-jar-plugin
        2.3.2
       
           
                true
                src/main/resources/META-INF/MANIFEST.MF
               
                   
               

           

       

   

   
        org.apache.maven.plugins
        maven-shade-plugin
       
           
                package
               
                    shade
               

           

       

       
           
               
                    javassist:javassist:jar:
                    net.bytebuddy:byte-buddy:jar:
                    net.bytebuddy:byte-buddy-agent:jar:
               

           

       

   

   
        org.apache.maven.plugins
        maven-compiler-plugin
       
            1.7
            1.7
       

   




2、实现一个Agent
Agent的构造比较简单,我们只需要在premain方法中,加入一个线程池。其功能是每隔5秒输出一次内存信息和GC信息。

public class MyAgent {

    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("this is an perform monitor agent.");

        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
            public void run() {
                Metric.printMemoryInfo();
                Metric.printGCInfo();
            }
        }, 0, 5000, TimeUnit.MILLISECONDS);
    }
}

3、获取JVM 内存以及GC信息
public class Metric {
    private static final long MB = 1048576L;

    public static void printMemoryInfo() {
        MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
        MemoryUsage headMemory = memory.getHeapMemoryUsage();

        String info = String.format("\ninit: %s\t max: %s\t used: %s\t committed: %s\t use rate: %s\n",
                headMemory.getInit() / MB + "MB",
                headMemory.getMax() / MB + "MB", headMemory.getUsed() / MB + "MB",
                headMemory.getCommitted() / MB + "MB",
                headMemory.getUsed() * 100 / headMemory.getCommitted() + "%"

        );

        System.out.print(info);

        MemoryUsage nonheadMemory = memory.getNonHeapMemoryUsage();

        info = String.format("init: %s\t max: %s\t used: %s\t committed: %s\t use rate: %s\n",
                nonheadMemory.getInit() / MB + "MB",
                nonheadMemory.getMax() / MB + "MB", nonheadMemory.getUsed() / MB + "MB",
                nonheadMemory.getCommitted() / MB + "MB",
                nonheadMemory.getUsed() * 100 / nonheadMemory.getCommitted() + "%"

        );
        System.out.println(info);
    }

    public static void printGCInfo() {
        List garbages = ManagementFactory.getGarbageCollectorMXBeans();
        for (GarbageCollectorMXBean garbage : garbages) {
            String info = String.format("name: %s\t count:%s\t took:%s\t pool name:%s",
                    garbage.getName(),
                    garbage.getCollectionCount(),
                    garbage.getCollectionTime(),
                    Arrays.deepToString(garbage.getMemoryPoolNames()));
            System.out.println(info);
        }
    }
}

三、运行
public class AgentTest {

    public static void main(String[] args) throws Exception {
        boolean is = true;
        while (is) {
            List list = new ArrayList();
            list.add("hello world");
        }
    }
}

运行上述代码时,我们同样加上Agent。-javaagent:./my-agent.jar
 

你可能感兴趣的:(JAVA进阶知识总结)