JMX Redux

by Juan C. Dueqas, Manuel Santillan, & Jose Luis Ruiz



Example 1:



MemoryMXBean memory=ManagementFactory.getMemoryMXBean();

MemoryUsage usage=memory.getHeapMemoryUsage();

System.out.println("Commited memory (Bytes): "+usage.getCommitted());



Example 2:



MBeanServerConnection serverconn=ManagementFactory.getPlatformMBeanServer();

ObjectName memoryObjName=ObjectName.getInstance(ManagementFactory.MEMORY_MXBEAN_NAME);

Object compositeData=serverconn.getAttribute(memoryObjName, "HeapMemoryUsage");

MemoryUsage usage=MemoryUsage.from((CompositeData)compositeData);

System.out.println("Commited memory (Bytes): "+usage.getCommitted());





Example 3:



MBeanServerConnection serverconn=ManagementFactory.getPlatformMBeanServer();

MemoryMXBean memory=new MemoryProxy(serverconn);

MemoryUsage usage=memory.getHeapMemoryUsage();

System.out.println("Commited memory (Bytes): "+usage.getCommitted());



Example 4:



JMXConnector con=JMXConnectorFactory.connect(new JMXServiceURL("rmi", "alfheim.dit.upm.es", 1099, "server"));

MBeanServerConnection serverconn=con.getMBeanServerConnection();

ObjectName memoryObjName=ObjectName.getInstance(ManagementFactory.MEMORY_MXBEAN_NAME);

Object compositeData=serverconn.getAttribute(memoryObjName, "HeapMemoryUsage");

MemoryUsage usage=MemoryUsage.from((CompositeData)compositeData);

System.out.println("Commited memory (Bytes): "+usage.getCommitted());





Example 5:



JMXConnector con=JMXConnectorFactory.connect(new JMXServiceURL("rmi", "host", 80, "path"));

MBeanServerConnection serverconn=con.getMBeanServerConnection();

MemoryMXBean memory=new MemoryProxy(serverconn);

MemoryUsage usage=memory.getHeapMemoryUsage();

System.out.println("Commited memory (Bytes): "+usage.getCommitted());





Example 6:



MBeanServerConnection mbserver=ManagementFactory.getPlatformMBeanServer();

JMXConnectorServer conn=JMXConnectorServerFactory.newJMXConnectorServer(new JMXServiceURL("rmi", "alfheim.dit.upm.es", 1099, "server"), null, (MBeanServer)mbserver);

conn.start();







Listing One

package ddjarticle;



import java.lang.management.*;

import javax.management.*;

import javax.management.openmbean.*;



/**

 * Listing One A proxy for the MemoryMXBean

 *

 * @author Manuel Santillan

 *

 */

public class MemoryProxy implements MemoryMXBean {

    private MBeanServerConnection server;



    private ObjectName oname;



    public MemoryProxy(MBeanServerConnection server) throws Exception {

        this.server = server;

        this.oname = ObjectName

                .getInstance(ManagementFactory.MEMORY_MXBEAN_NAME);

    }



    public int getObjectPendingFinalizationCount() {

        try {

            return ((Integer) server.getAttribute(oname,

                    "ObjectPendingFinalizationCount")).intValue();

        } catch (Exception e) {

            e.printStackTrace();

            return 0;

        }



    }



    public MemoryUsage getHeapMemoryUsage() {

        try {

            Object usage = server.getAttribute(oname, "HeapMemoryUsage");

            return MemoryUsage.from((CompositeData) usage);

        } catch (Exception e) {

            e.printStackTrace();

            return null;

        }

    }



    public MemoryUsage getNonHeapMemoryUsage() {

        try {

            Object usage = server.getAttribute(oname, "NonHeapMemoryUsage");

            return MemoryUsage.from((CompositeData) usage);

        } catch (Exception e) {

            e.printStackTrace();

            return null;

        }

    }



    public boolean isVerbose() {

        try {

            return ((Boolean) server.getAttribute(oname, "Verbose"))

                    .booleanValue();

        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }

    }



    public void setVerbose(boolean value) {

        try {

            Attribute at = new Attribute("Verbose", new Boolean(value));

            server.setAttribute(oname, at);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }



    public void gc() {

        try {

            server.invoke(oname, "gc", null, null);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}





Listing Two



package ddjarticle;



import java.lang.management.*;

import javax.management.*;

import javax.management.openmbean.*;

import java.util.*;



/**

 * <p>

 * This is a memory policy example. This code creates "important data" and

 * "unimportant data". When threshold is exceeded, unimportant data is removed.

 * </p>

 *

 * @author Manuel Santillan

 *

 */

public class ListingTwo_MemoryPolicy implements Runnable, NotificationListener {

    public static final long MEMORY_THRESHOLD = 10000000;



    private Hashtable importantObjects;



    private Hashtable unimportantObjects;



    private int key;



    private byte[] unimportantDataUnit;



    private byte[] importantDataUnit;



    public ListingTwo_MemoryPolicy() {

        importantObjects = new Hashtable();

        unimportantObjects = new Hashtable();

        key = 0;

        this.unimportantDataUnit = new byte[100 * 1024];

        this.importantDataUnit = new byte[1024];

    }



    public void run() {

        while (true) {

            try {

                //Each millisecond we create 100KB of unimportant data and 1KB

                // of important data.

                this.addData();

                Thread.sleep(1);

            } catch (InterruptedException ie) {

            }

            key++;

        }

    }



    public void handleNotification(Notification notification, Object handback) {

        if (notification.getType().equals(

                MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) {

            MemoryNotificationInfo info = MemoryNotificationInfo

                    .from((CompositeData) notification.getUserData());

            MemoryMXBean memory = ManagementFactory.getMemoryMXBean();

            long current = memory.getHeapMemoryUsage().getUsed();

            System.out.println("THRESHOLD_EXCEEDED notification received");

            System.out.println("Current memory used: " + current

                    + " and threshold: " + MEMORY_THRESHOLD);

            System.out.println("Freeing unimportant memory...");

            clean();

            System.gc();

            current = memory.getHeapMemoryUsage().getUsed();

            System.out.println("Current: " + current);

            if (current < MEMORY_THRESHOLD) {

                System.out.println("done");

            } else

                System.out.println("Could not free enough memory. ");

        }

    }



    private synchronized void addData() {

        this.importantObjects.put(new Integer(key), importantDataUnit.clone());

        this.unimportantObjects.put(new Integer(key), unimportantDataUnit

                .clone());

    }



    private synchronized void clean() {

        this.unimportantObjects.clear();

    }



    public static void main(String[] args) throws Exception {

        ListingTwo_MemoryPolicy example = new ListingTwo_MemoryPolicy();

        Thread t = new Thread(example);

        MBeanServerConnection server = ManagementFactory

                .getPlatformMBeanServer();

        NotificationFilterSupport filter = new NotificationFilterSupport();

        filter.enableType(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED);

        server.addNotificationListener(ObjectName

                .getInstance(ManagementFactory.MEMORY_MXBEAN_NAME), example,

                filter, null);

        ListingTwo_MemoryPolicy.getTenuredGenPool().setUsageThreshold(

                MEMORY_THRESHOLD);

        t.start();

    }



    private static MemoryPoolMXBean getTenuredGenPool() {

        //In the reference implementation, the only heap memory space that

        // supports threshold is the tenured gen one

        //this is reasonable, as the other ones are for very short lived

        // objects

        List list = ManagementFactory.getMemoryPoolMXBeans();

        MemoryPoolMXBean mp;

        MemoryPoolMXBean tenured = null;

        for (int i = 0; i < list.size(); i++) {

            mp = (MemoryPoolMXBean) list.get(i);

            if (mp.getName().equals("Tenured Gen"))

                tenured = mp;

        }

        return tenured;

    }

}





Listing Three



package ddjarticle;



import java.lang.management.ManagementFactory;

import java.util.HashMap;

import java.util.Map;



import javax.management.MBeanServer;

import javax.management.remote.JMXConnectorServer;

import javax.management.remote.JMXConnectorServerFactory;

import javax.management.remote.JMXServiceURL;



/**

 * <p>

 * It starts a simple SOAP connector server. In order to have it working

 * properly, you need to have in your classpath:

 * </p>

 * <ul>

 * <il>mx4j-tools.jar from <a href="http://mx4j.sourceforge.net">MX4J. /a> You

 * might need to recompile with a Axis 1.2 to have it working in Java 5.0 </il>

 * <il>axis.jar version 1.2 and all its related jars </il>

 * <il>org.mortbay.jetty.jar and related </il>

 * </ul>

 *

 * @author Manuel Santillan DIT-UPM

 */

public class SOAPserver {

    /**

     * This class is an example using mx4j's soap connector. It implements the

     * server part. the SOAPClient class implements a simple example client We

     * use java 1.5, so we have recompiled mx4j with axis1.2rc1

     */

    public static void main(String[] args) throws Exception {

        MBeanServer server = ManagementFactory.getPlatformMBeanServer();

        Map environment = new HashMap();

        //We need to specify the provider packages whereJMX will search for the

        // protocols.

        //If not, it won't find the SOAP connector

        //We can use an existing axis framework. To do that, you must add some

        // other properties to the environment.

        //See MX4J documentation (http://mx4j.sourceforge.net) for details.

        environment.put(JMXConnectorServerFactory.PROTOCOL_PROVIDER_PACKAGES,

                "mx4j.tools.remote.provider");

        JMXServiceURL url = new JMXServiceURL("soap", "cauca.dit.upm.es", 8080,

                "/jmxconnector");

        JMXConnectorServer conn = JMXConnectorServerFactory

                .newJMXConnectorServer(url, environment, server);

        conn.start();

    }

}





Listing Four



package ddjarticle;



import java.util.*;

import java.io.*;

import javax.management.*;

import javax.management.remote.*;



import org.apache.axis.enum.Enum;



/**

 * Simple text-based SOAP console that accepts just one command

 *

 * @author Manuel Santillan

 *

 *

 */

//What you need to run these examples

public class SOAPConsole implements Runnable {

    private MBeanServerConnection server;



    public static final String COMMAND_NAME = "list";



    private SOAPConsole(MBeanServerConnection server) {

        this.server = server;

    }



    public static void main(String[] args) throws Exception {

        //First we set the connector, with the *SAME* URL as the server

        Map environment = new HashMap();

        environment.put(JMXConnectorServerFactory.PROTOCOL_PROVIDER_PACKAGES,

                "mx4j.tools.remote.provider");

        JMXServiceURL url = new JMXServiceURL("soap", "cauca.dit.upm.es", 8080,

                "/jmxconnector");

        JMXConnector cntor = JMXConnectorFactory.connect(url, environment);

        //Then we get a connection which behaves as if we were inside remote

        // the MBeanServer

        SOAPConsole console = new SOAPConsole(cntor.getMBeanServerConnection());

        Thread t = new Thread(console);

        t.start();

    }



    private void printMBeans(ObjectName filter) throws Exception {

        //Our console is very simple.

        //It has just one command: listobjects (String filtername)

        Iterator it = server.queryNames(filter, null).iterator();

        System.out.println("The MBeans that match your query are: ");

        while (it.hasNext()) {

            System.out.println("\t" + it.next());

        }

    }



    public void run() {

        while (true) {

            try {

                BufferedReader br = new BufferedReader(new InputStreamReader(

                        System.in));

                String line = br.readLine();

                String[] command = line.split(" ");

                //We only support one command

                if (command[0].equalsIgnoreCase("exit"))

                    System.exit(0);

                if (!command[0].equalsIgnoreCase(SOAPConsole.COMMAND_NAME)

                        || command.length > 2) {

                    System.out.println("Syntax: list [filter] or exit");

                    continue;

                }

                //If length =1 then filter=null

                if (command.length == 1)

                    printMBeans(null);

                else

                    printMBeans(ObjectName.getInstance(command[1]));

            } catch (MalformedObjectNameException moe) {

                System.out

                        .println("Invalid filter. check

javax.management.ObjectName for correct filter syntax.");

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

    }

}





1



