天天看點

[Java]JMX

在JVM中有一些經常使用的MBeans,能夠寫個代碼擷取到:

public class Test {
    public static void main(String[] args) throws Exception {
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        Set instances = server.queryMBeans(null, null);
        Iterator iterator = instances.iterator();
        while (iterator.hasNext()) {
            ObjectInstance instance = (ObjectInstance) iterator.next();
            System.out.println("MBean Found:");
            System.out.println("Class Name:\t" + instance.getClassName());
            System.out.println("Object Name:\t" + instance.getObjectName());
            System.out.println("****************************************");
        }
    }
}      

依據清單,我們就能通過MBean來擷取想要的資訊了,比方擷取Code Cache的大小:

public class TestMBean {
    final static String pid               = "6228";
    final static String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress";

    public static void main(String[] args) throws Exception {
        VirtualMachine vm = VirtualMachine.attach(pid);
        JMXConnector connector = null;
        String connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);

        String agent = vm.getSystemProperties().getProperty("java.home") + File.separator + "lib" + File.separator
                + "management-agent.jar";
        vm.loadAgent(agent);

        connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
        JMXServiceURL url = new JMXServiceURL(connectorAddress);
        connector = JMXConnectorFactory.connect(url);
        MBeanServerConnection mbeanConn = connector.getMBeanServerConnection();
        ObjectName name = new ObjectName("java.lang:type=MemoryPool,name=Code Cache");
        System.out.println(mbeanConn.getAttribute(name, "Usage"));

        if (connector != null) {
            connector.close();
        }
        vm.detach();
    }
}      

實際上通過ObjectName("java.lang:type=MemoryPool,name=Code Cache")得到的類為:

sun.management.MemoryPoolImpl      

而在getAttribute(name, "Usage")的時候相應調用的方法為:

public java.lang.management.MemoryUsage getUsage(){}      

其它MBean的使用方法和這個類似。

---------- ---------- ---------- ---------- ----------風格線---------- ---------- ---------- ---------- ----------

假設系統的MBean不能滿足須要,那麼我們能夠自定義MBean,比方标準的MBean例如以下:

// 标準的MBean有幾個限制:1、必須實作接口 2、必須有public類型的構造函數 3、命名規則
public class My implements MyMBean {
    public String getHello() {
        return "hello world";
    }
}
public interface MyMBean {
    public String getHello();
}      

接下來能夠将這個MBean增加MBeanServer:

public class Test {
    public static final void main(String[] args) throws Exception {
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        ObjectName objectName = new ObjectName("com.wszt:type=MyMBean");
        mBeanServer.createMBean("My", objectName);
    }
}      

attach&用法和上面的一樣,不贅述。除了标準的MBean還有Dynamic MBean、Model Bean、Open MBean,用法類似。

簡單來看JMX是一個JVM的管理架構,MBean是對資源的封裝,然後後AGENT來進行包裝,最後有接口對外提供以友善使用,看下圖:

[Java]JMX