Hi,

If we want to analyse the Heap & Non-Heap Usages of JBoss Application Server’s JVM remotely then we can use JConsole, Visual JVM etc. Apart from these utilities we can also use the following Simple JMX Code.

You can enhance this tiny code to Develop your own Mini/Light weight class where you can add your Java Mail API code to send an automated alert to the Administrator as soon as the monitoring statistics becomes abnormal or to perform some activities like collecting Thread dumps etc.

To connect to the actual JConsole remotely also we need to provide the following JAVA_OPTS inside our “$JBOSS_HOME/bin/run.conf” or inside “$PROFILE/run.conf” file (NOTE: for windows machines we can add this JAVA_OPTS inside “%JBOSS_HOME/bin/run.conf.bat” or “%PROFILE%/run.conf.bat”) and the connection url format should be:

service:jmx:rmi:///jndi/rmi://"+hostname+":"+port+"/jmxrmi

Step1). Edit the “%JBOSS_HOME%/bin/run.conf.bat” or “%JBOSS_HOME%/bin/run.bat” (Server StartScript configuration file) and then set the following JAVA_OPTS there.

set JAVA_OPTS="%JAVA_OPTS% -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=4545 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl -Djboss.platform.mbeanserver"

For Unix Based Operating System edit the “$JBOSS_HOME/bin/run.conf” OR “$JBOSS_HOME/bin/run.sh” OR “$PROFILE/run.conf” file as following:

JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=4545 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl -Djboss.platform.mbeanserver"

Make sure that the 4545 is not being used by any other process. Or define any other port in above parameter which is free.

Step2). Now from any other box or from the same Box you can run the Following JMX code to get Heap & Non Heap Usages of the JVM:
“HeapAndNonHeapMonitoring.java”

import java.util.Hashtable;
import java.io.*;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
import java.lang.management.MemoryMXBean;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import javax.management.*;
import javax.management.openmbean.CompositeDataSupport;

public class HeapAndNonHeapMonitoring
{
	private static MBeanServerConnection connection;
	private static JMXConnector connector;
public static void Connection(String hostname, String port) throws IOException
	{
	Integer portInteger = Integer.valueOf(port);
	Hashtable h = new Hashtable();
	JMXServiceURL address = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+hostname+":"+port+"/jmxrmi");
	connector = JMXConnectorFactory.connect(address,null);
	connection = connector.getMBeanServerConnection();
	System.out.println("GOT THE MBeanServerConnection---SUCCESSFULLY");
	}

private static void doGarbageCollection() throws Exception
{
	ObjectName memoryMXBean=new ObjectName("java.lang:type=Memory");
	connection.invoke(memoryMXBean,"gc", null, null);
	System.out.println("nnt------Garbage Collection Done Successfully-----");
}

private static void doOperatingSystemDetails() throws Exception
{
	ObjectName operatingSystemMXBean=new ObjectName("java.lang:type=OperatingSystem");
	Object systemLoadAverage = connection.getAttribute(operatingSystemMXBean, "SystemLoadAverage");

	Long freePhysicalMemory = (Long) connection.getAttribute(operatingSystemMXBean, "FreePhysicalMemorySize");
	Long processCpuTime = (Long) connection.getAttribute(operatingSystemMXBean, "ProcessCpuTime");
	Long committedVirtualMemorySize = (Long) connection.getAttribute(operatingSystemMXBean, "CommittedVirtualMemorySize");
	Long freeSwapSpaceSize = (Long) connection.getAttribute(operatingSystemMXBean, "FreeSwapSpaceSize");
	Long totalPhysicalMemorySize = (Long) connection.getAttribute(operatingSystemMXBean, "TotalPhysicalMemorySize");
	Long totalSwapSpaceSize = (Long) connection.getAttribute(operatingSystemMXBean, "TotalSwapSpaceSize");

	System.out.println("Operating SystemLoadAverage: " + systemLoadAverage);
	System.out.println("Operating System FreePhysicalMemory: " + (freePhysicalMemory/(1024*1024))+"-MB");
	System.out.println("Operating System processCpuTime: " + processCpuTime);
	System.out.println("Operating System committedVirtualMemorySize: " + (committedVirtualMemorySize/(1024*1024))+"-MB");
	System.out.println("Operating System freeSwapSpaceSize: " + (freeSwapSpaceSize/(1024*1024))+"-MB");
	System.out.println("Operating System totalPhysicalMemorySize: " + (totalPhysicalMemorySize/(1024*1024))+"-MB");
	System.out.println("Operating System totalSwapSpaceSize: " + (totalSwapSpaceSize/(1024*1024))+"-MB");
}

private static void getHeapMemoryUsage() throws Exception
{
	ObjectName memoryMXBean=new ObjectName("java.lang:type=Memory");
	CompositeDataSupport dataSenders = (CompositeDataSupport) connection.getAttribute(memoryMXBean,"HeapMemoryUsage");
	if (dataSenders != null)
	  {
		Long commited = (Long) dataSenders.get("committed");
		Long init = (Long) dataSenders.get("init");
		Long max = (Long) dataSenders.get("max");
		Long used = (Long) dataSenders.get("used");
		Long percentage = ((used * 100) / max);
		System.out.println("nnt commited   : "+commited/(1024*1024)+" MB");
		System.out.println("t init       : "+init/(1024*1024)+" MB");
		System.out.println("t max        : "+max/(1024*1024)+" MB");
		System.out.println("t used       : "+used/(1024*1024)+" MB");
		System.out.println("t percentage : "+percentage +" %");
	   }
}

private static void getNonHeapMemoryUsage() throws Exception
{
	ObjectName memoryMXBean=new ObjectName("java.lang:type=Memory");
	CompositeDataSupport dataSenders = (CompositeDataSupport) connection.getAttribute(memoryMXBean,"NonHeapMemoryUsage");
	if (dataSenders != null)
	{
		Long commited = (Long) dataSenders.get("committed");
		Long init = (Long) dataSenders.get("init");
		Long max = (Long) dataSenders.get("max");
		Long used = (Long) dataSenders.get("used");
		Long percentage = ((used * 100) / max);
		System.out.println("nnt commited   : "+commited/(1024*1024)+" MB");
		System.out.println("t init       : "+init/(1024*1024)+" MB");
		System.out.println("t max        : "+max/(1024*1024)+" MB");
		System.out.println("t used       : "+used/(1024*1024)+" MB");
		System.out.println("t percentage : "+percentage +" %");
	}
}

public static void main(String[] args) throws Exception
     {
	String hostname = args[0];
	String port = args[1];
	Connection(hostname, port);
	//doGarbageCollection();                // --> use this method if you want to perform Garbage Collection
	System.out.println("nt----------HEAP Memory Usages---------");
	getHeapMemoryUsage();
	System.out.println("nt----------Non-HEAP Memory Usages---------");
	getNonHeapMemoryUsage();
	System.out.println("nt----------Operating System Usages---------");
	doOperatingSystemDetails();
	connector.close();
     }
}

Step3). Compile and run the above program as following:

javac  HeapAndNonHeapMonitoring.java
java  HeapAndNonHeapMonitoring  10.10.10.10  4545

Here 10.10.10.10 is the JBoss Server Listen Address.
4545 is the port -Dcom.sun.management.jmxremote.port defined in the JAVA_OPTS

OUTPUT:

java HeapAndNonHeapMonitoring localhost 4545
GOT THE MBeanServerConnection---SUCCESSFULLY

	----------HEAP Memory Usages---------
	 commited   : 384 MB
	 init       : 58 MB
	 max        : 837 MB
	 used       : 344 MB
	 percentage : 41 %

	----------Non-HEAP Memory Usages---------
	 commited   : 79 MB
	 init       : 23 MB
	 max        : 214 MB
	 used       : 75 MB
	 percentage : 35 %

	----------Operating System Usages---------
	Operating System LoadAverage: 0.38
	Operating System FreePhysicalMemory: 650-MB
	Operating System processCpuTime: 54850000000
	Operating System committedVirtualMemorySize: 3396-MB
	Operating System freeSwapSpaceSize: 5813-MB
	Operating System totalPhysicalMemorySize: 3760-MB
	Operating System totalSwapSpaceSize: 5823-MB

NOTE: Do not start your JBoss instance on bind address 0.0.0.0 which creates problem while RMI communication.

.
.
Thanks
Middleware Magic Team

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.