20

I'm looking for sample Java JMX code to access the values of JMX attributes from another VM.

With JConsole, I have no problem looking at java.lang/Memory/Attributes/HeapMemory

How would I get the same information from a Java program running in a VM?

Examples of any command line options needed, or other things that need to be started appreciated.

0

4 Answers 4

18

You need to setup a JMXConnector. Here is a code snippet that will get the committed heap memory usage on a remote machine.

String host ="myHost";
int port = 1234;
HashMap map = new HashMap();
String[] credentials = new String[2];
credentials[0] = user;
credentials[1] = password;
map.put("jmx.remote.credentials", credentials);
JMXConnector c = JMXConnectorFactory.newJMXConnector(createConnectionURL(host, port), map);
c.connect();
Object o = c.getMBeanServerConnection().getAttribute(new ObjectName("java.lang:type=Memory"), "HeapMemoryUsage");
CompositeData cd = (CompositeData) o;
System.out.println(cd.get("committed"));

private static JMXServiceURL createConnectionURL(String host, int port) throws MalformedURLException
{
    return new JMXServiceURL("rmi", "", 0, "/jndi/rmi://" + host + ":" + port + "/jmxrmi");
}

If you don't care about security you can set the map to null. You need to start up the remote server with;

-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

You might want to take a look at wlshell which is a small utility that allows you to access MBeans on a remote server using a text interface or a script, It can be used with WebLogic, but it works for any Java program where you have enabled remote monitoring.

Sign up to request clarification or add additional context in comments.

2 Comments

How do we know the user & password or how can we set it. By using a property file?
MemoryUsage memuse = MemoryUsage.from((CompositeData) o);
5

@Kire's answer looks good but I thought I'd add some details about my SimpleJMX package. It contains server support that allows you to export beans easily and also includes a simple client interface that works against any JVM that exports JMX information.

To access memory usage you'd do something like:

JmxClient client = new JmxClient("some.host.name", somePortNumber);
// get the memory composite information
CompositeData composite =
      (CompositeData)client.getAttribute(new ObjectName("java.lang:type=Memory"),
                                         "HeapMemoryUsage");
System.out.println(composite.get("committed"));

2 Comments

@Gray looks nice, does SimpleJMX client work with standard JMX server?
It does @raffian. It just uses the JMX protocol so works with any JMX client/server.
2
// Retrieve memory managed bean from management factory.
MemoryMXBean memBean = ManagementFactory.getMemoryMXBean() ;
MemoryUsage heap = memBean.getHeapMemoryUsage();
MemoryUsage nonHeap = memBean.getNonHeapMemoryUsage();

// Retrieve the four values stored within MemoryUsage:
// init: Amount of memory in bytes that the JVM initially requests from the OS.
// used: Amount of memory used.
// committed: Amount of memory that is committed for the JVM to use.
// max: Maximum amount of memory that can be used for memory management.
System.err.println(String.format("Heap: Init: %d, Used: %d, Committed: %d, Max.: %d",
  heap.getInit(), heap.getUsed(), heap.getCommitted(), heap.getMax()));
System.err.println(String.format("Non-Heap: Init: %d, Used: %d, Committed: %d, Max.: %d",
  nonHeap.getInit(), nonHeap.getUsed(), nonHeap.getCommitted(), nonHeap.getMax()));

2 Comments

Unless I'm very confused, that's code to access information about the same vm. What I'm trying to figure out is how to write a little command line script that will pull information from a running server in a differnt VM.
@ThoughtfulHacking you are right, this code is for the same vm, I was trying to do the same code on other vm, there is a method in ManagementFactory named newPlatformMXBeanProxy I used it to get the threads of another vm, but I wasn't able to do the same to get the memory management. Your question's correct answer is the solution, but I really need to do it like this answer...
1

This is how you get the MemoryMXBean remotely (to complement @Adamski's answer):

MemoryMXBean memoryMXBeanProxy = JMX.newMXBeanProxy(
            conn, new ObjectName("java.lang:type=Memory"), MemoryMXBean.class);

1 Comment

This solution is better than the @Kire one, as there is no need to use casts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.