How do I access memory usage programmatically via JMX?
Asked Answered
P

4

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.

Passing answered 18/11, 2009 at 23:19 Comment(0)
O
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.

Okelley answered 23/11, 2009 at 0:57 Comment(2)
How do we know the user & password or how can we set it. By using a property file?Dulla
MemoryUsage memuse = MemoryUsage.from((CompositeData) o);Fetch
A
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"));
Ambary answered 21/6, 2012 at 14:58 Comment(2)
@Ambary looks nice, does SimpleJMX client work with standard JMX server?Brutalize
It does @raffian. It just uses the JMX protocol so works with any JMX client/server.Ambary
B
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()));
Brion answered 18/11, 2009 at 23:34 Comment(2)
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.Passing
@Passing 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...Chlori
P
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);
Putrefaction answered 13/10, 2017 at 15:52 Comment(1)
This solution is better than the @Kire one, as there is no need to use casts.Tade

© 2022 - 2024 — McMap. All rights reserved.