Starting with Java 5, the JDK provides some JVM detection APIs, a well-known java.lang.management package that provides many Mxbean interface classes that are easily accessible to the JVM's memory, GC, Thread, lock, class, Even the operating system level of various information, this article simply introduces a Java process using JMX CPU, heap memory use of monitoring. Some people may feel that there is no need to do this, because tools such as jconsole can be done and will be more detailed than the examples in this article. But sometimes the console does not have to be able to monitor the Java process as a system service, and I have recently had to encode myself to get the monitoring data for the remote Java process. Hope to be able to play a role in it.
First, a brief overview of JMX (Java Management Extensions), the Java Management extension, is used to monitor and manage the JVM and the operating system it is running. At present, the Java platform mainly provides the following figure shown in the 9 Mxbean, the role of each mxbean based on the class name can probably guess a few, specific to check the API.
The Mxbean in the Java.lang.management package provides the basic functionality to enhance some features in sum.com.management, and of course we can provide our own Mxbean according to the JMX specification.
I mainly use Java.lang.management.MemoryMXBean and Sun.com.management.OperatingSystemMXBean to monitor the memory and CPU of remote Java respectively. According to the demand 5 seconds to read data, memory is mainly used heap memory,cpu is the main use rate.
Before using Operatingsystemmxbean and Memorymxbean, you must first get jmxconnector and create mbeanserverconnnection, With this connection we can use Managementfactory to create the mxbean we need, and the class-dependent diagram is as follows:
Sample code: Java code /* * host: remote machine IP address * port: remote Java processes running Jmxremote ports */ jmxserviceurl serviceurl = new Jmxserviceurl ( host,port ); jmxconnector conn = Jmxconnectorfactory.connect (serviceurl); mbeanserverconnection mbs= Conn.getmbeanserverconnection (); /Get remote memorymxbean memorymxbean membean=managementfactory.newplatformmxbeanproxy (mbs,managementfactory.memory_mxbean_name, Memorymxbean.class); //Get remote opretingsystemmxbean Com.sun.management.OperatingSystemMXBean opMXbean = Managementfactory.newplatformmxbeanproxy (mbs, Managementfactory.operating_ System_mxbean_name, operatingsystemmxbean.class);
then, the collection of memory data is relatively simple, direct call API get: Java code /** collect data every 5 seconds */ try { timeunit.seconds.sleep (5); } catch ( Interruptedexception e) { logger.error ("Interruptedexception occurred while memorycollector sleeping ... "); } memoryusage heap = membean etheapmemoryusage (); MemoryUsage nonHeap = memBean etnonheapmemoryusage (); long heapsizeused = Heap.getused ()//heap Use size long nonheapsizeused = nonheap.getused (); long heapcommitedsize = heap.getcommitted (); long nonheapcommitedsize = nonheap.getcommitted ();
CPU utilization needs to be calculated on its own, because the API only provides access to CPU time, I have to two times in the system time interval to obtain two CPU time, to get at that time interval CPU use time, Division is the use of CPU, of course, the error certainly exists. Calculate CPU Usage Code Long start = System.currenttimemillis (); long startt = opmxbean.getprocesscputime (); /** Collect data every 5 seconds */ try { timeunit.seconds.sleep (5); } catch (interruptedexception e) { logger.error ("interruptedexception occurred while MemorYcollector sleeping ... "); } long end = system.currenttimemillis (); long endt = opmxbean.getprocesscputime (); //end - start is the current collection of time units, Unit ms //endt - startt for the current time unit CPU use time , the unit is ns //So:double ratio = (Entt-startt)/1000000.0/(End-start)/ Opmxbean.getavailableprocessors ()
That's the core code. Of course, the specific use of the words should use a separate thread CPU, memory data, read the data need to write files or drawings, monitoring time is also to be timed to the data to the disk file or database, and so on, these are the digression. Here I write in Excel, and then in Excel graphics display, remote monitoring of the program is not convenient to display, just to monitora program that simulates a CPU sine curveTo see if the data I've monitored (graphics) is consistent with expectations, and what's the difference with Jconsole: The program being tested, the analog CPU sinusoidal code public class sincpu { public static final double time = 1000 ; /** * @param args the command line arguments */ public static void main (String[] args) throws interruptedexception { new thread (New sintask ()). Start (); } static class sintask implements runnable{ @Override public void run () { double x = 0; double y = 0; while ( true) { y = (Math.sin (x) + 1) * TIME / 2; dosomesimplework (y); x + = 0.1; try { thread.sleep ((Long) (time - y)); } catch ( Interruptedexception e) { e.printstacktrace (); } } } private void dosomesimplework ( Double y) { long starttime = systeM.currenttimemillis (); while ((System.currenttimemillis () - starttime) < y) { } } } }
The monitoring results are basically the same as expected, and the CPU data graph presents the expected sine curve:
In the figure above, the first figure is cut from the Jconsole monitor diagram, and the following figure is I use Opmxbean calculation to obtain, two graphs basically coincide, the data basic fluctuation in 0-25% is because I test the machine is the four cores CPU, the two images have the displacement because, I manually open jconsole without my program monitoring to come fast, so the approximate image translation under the Basic Agreement.
The memory test should be more accurate than the CPU, there is no paste. Note: If the monitoring of the number of program threads, the CPU will have a more obvious error, and the frequency of mining is not high enough may be some point leakage.
Finally: The test program must open the Jmxremote port, the specific use of parameters:
-dcom.sun.management.jmxremote-dcom.sun.management.jmxremote.port=[Open Ports]
-dcom.sun.management.jmxremote.authenticate=false
-dcom.sun.management.jmxremote.ssl=false