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

声明:原创文章,转载请注明出处。http://www.jianshu.com/p/9d86c7e653cb

Java字节码系列
Java字节码1-Agent简单上手
Java字节码2-instrument初体验
Java字节码3-使用ByteBuddy实现一个Java-Agent
Java字节码4-使用Java-Agent实现一个JVM监控工具
本系列代码可见:https://github.com/hawkingfoo/demo-agent

一、概述

在前面几节当中,我们构造了多个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字节码4-使用Java-Agent实现一个JVM监控工具_第1张图片
image.png

你可能感兴趣的:(Java字节码4-使用Java-Agent实现一个JVM监控工具)