使用JMXhtml
JAVA Management Extensions的縮寫,Java自帶的一種管理資源的技術,好比對Java 應用程序,系統和網絡等java
java自帶的java.lang.management.ManagementFactory 能夠看到它提供的一些列方法:瀏覽器
能夠看到它提供了包括類加載、內存、線程等MXBean以Memory爲例,它包括兩部分,MemoryMXBean和MemoryPoolMXBeanbash
/**
* Returns the managed bean for the memory system of
* the Java virtual machine.
*
* @return a {@link MemoryMXBean} object for the Java virtual machine.
*/
public static MemoryMXBean getMemoryMXBean() {
return ManagementFactoryHelper.getMemoryMXBean();
}
複製代碼
MemoryMXBean提供獲取堆內存和非堆內存的方法,返回對象MemoryUsage相應包含最大、已使用等信息網絡
/**
* Returns the current memory usage of the heap that
* is used for object allocation. The heap consists
* of one or more memory pools. The <tt>used</tt>
* and <tt>committed</tt> size of the returned memory
* usage is the sum of those values of all heap memory pools
* whereas the <tt>init</tt> and <tt>max</tt> size of the
* returned memory usage represents the setting of the heap
* memory which may not be the sum of those of all heap
* memory pools.
* <p>
* The amount of used memory in the returned memory usage
* is the amount of memory occupied by both live objects
* and garbage objects that have not been collected, if any.
*
* <p>
* <b>MBeanServer access</b>:<br>
* The mapped type of <tt>MemoryUsage</tt> is
* <tt>CompositeData</tt> with attributes as specified in
* {@link MemoryUsage#from MemoryUsage}.
*
* @return a {@link MemoryUsage} object representing
* the heap memory usage.
*/
public MemoryUsage getHeapMemoryUsage();
/**
* Returns the current memory usage of non-heap memory that
* is used by the Java virtual machine.
* The non-heap memory consists of one or more memory pools.
* The <tt>used</tt> and <tt>committed</tt> size of the
* returned memory usage is the sum of those values of
* all non-heap memory pools whereas the <tt>init</tt>
* and <tt>max</tt> size of the returned memory usage
* represents the setting of the non-heap
* memory which may not be the sum of those of all non-heap
* memory pools.
*
* <p>
* <b>MBeanServer access</b>:<br>
* The mapped type of <tt>MemoryUsage</tt> is
* <tt>CompositeData</tt> with attributes as specified in
* {@link MemoryUsage#from MemoryUsage}.
*
* @return a {@link MemoryUsage} object representing
* the non-heap memory usage.
*/
public MemoryUsage getNonHeapMemoryUsage();
複製代碼
MemoryPoolMXBean可以獲取 memory pool的名字,好比是不是Eden區,old區等等架構
/**
* Returns a list of {@link MemoryPoolMXBean} objects in the
* Java virtual machine.
* The Java virtual machine can have one or more memory pools.
* It may add or remove memory pools during execution.
*
* @return a list of <tt>MemoryPoolMXBean</tt> objects.
*
*/
public static List<MemoryPoolMXBean> getMemoryPoolMXBeans() {
return ManagementFactoryHelper.getMemoryPoolMXBeans();
}
複製代碼
要獲取整個的內存大小,須要使用Runtimeoracle
/**
* Returns the amount of free memory in the Java Virtual Machine.
* Calling the
* <code>gc</code> method may result in increasing the value returned
* by <code>freeMemory.</code>
*
* @return an approximation to the total amount of memory currently
* available for future allocated objects, measured in bytes.
*/
public native long freeMemory();
/**
* Returns the total amount of memory in the Java virtual machine.
* The value returned by this method may vary over time, depending on
* the host environment.
* <p>
* Note that the amount of memory required to hold an object of any
* given type may be implementation-dependent.
*
* @return the total amount of memory currently available for current
* and future objects, measured in bytes.
*/
public native long totalMemory();
/**
* Returns the maximum amount of memory that the Java virtual machine will
* attempt to use. If there is no inherent limit then the value {@link
* java.lang.Long#MAX_VALUE} will be returned. </p>
*
* @return the maximum amount of memory that the virtual machine will
* attempt to use, measured in bytes
* @since 1.4
*/
public native long maxMemory();
複製代碼
經過java.lang.management.ManagementFactory 獲取 MBeanServer,平臺全部的MBean都會註冊到這個上面。而後經過獲取ObjectName和屬性就能得到值app
分紅3塊:Instrumentation,JMX agent和Remote managementdom
Instrumentation: 使用MBeans來實現資源檢測(resources' instrumentation),MBeans有一套標準的規範,實現MBeans必須遵循,以實現標準化的處理ide
JMX Agent: 用於直接的控制資源,並使得遠程管理應用可以獲取這些資源,它一般和控制的資源在同一臺機器上。JMX Agent的核心組件是MBean server[]MBeans註冊的地方]
Remote management: JMX Agent實現的不一樣協議適配器和connector使得註冊在MBean server上的MBeans都可以被看到,好比HTML的adaptor可以使得瀏覽器上可以展現MBean
一個MBean能夠表明一個設備,應用或者任何能夠被管理的資源。MBeans會暴漏具備以下特性的管理接口:
可讀可寫的屬性集合:讀對應着 get開頭的方法,必須有返回值;寫對應着set開頭的方法
可調用操做的集合:自定義的一下方法
一段自個人描述
包含兩個部分:MBean的接口和它的實現類。命名接口爲 xxxMBean 。好比命名爲 PaxiMBean,而後用一個java類 Paxi來實現這個接口。
MBean
package main.jmx;
public interface PaxiMBean {
void sayHi();
String getName();
void setName(String name);
}
複製代碼
Mbean實現
public class Paxi implements PaxiMBean {
@Override
public void sayHi() {
System.out.println("hi");
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name=name;
}
private String name="paxi";
}
複製代碼
Agent例子
package main.jmx;
public class MyAgent {
public static void main(String[] args) {
//1:獲取平臺已經建立並初始化的MBeanServer,沒有就經過MBeanServerFactory.createMBeanServer()建立
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
try {
//2:每一個MBean必須有一個object name,name遵守標準格式
ObjectName name = new ObjectName("main.jmx:type=Paxi");
Paxi paxi = new Paxi();
//3:註冊MBean
mbs.registerMBean(paxi,name);
System.out.println("wait for incoming request");
Thread.sleep(Long.MAX_VALUE);
} catch (MalformedObjectNameException e) {
e.printStackTrace();
} catch (NotCompliantMBeanException e) {
e.printStackTrace();
} catch (InstanceAlreadyExistsException e) {
e.printStackTrace();
} catch (MBeanRegistrationException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
複製代碼
在命令行運行 jconsole,選中MBean,點擊左側欄 main.jmx
獲得操做界面 點擊sayHi,會彈窗提示調用成功 此時界面上會出現 sayHi的內容wait for incoming request
hi
複製代碼
它是一種MBean的一種,僅用來引用一種預約義的數據類型。它的定義爲 方式能夠和MBean同樣。接口後綴爲MXBean而後在實現
public interface PaxiQMXBean {
PaxiQueue getPaxiQueue();
void clearQueue();
}
複製代碼
或者是使用MXBean的註解
@MXBean
public interface PaxiQInAnnotation {
PaxiQueue getPaxiQueue();
void clearQueue();
}
複製代碼
實現
public class PaxiQ implements PaxiQMXBean {
private Queue<String> queue;
public PaxiQ(Queue<String> queue) {
this.queue = queue;
}
@Override
public PaxiQueue getPaxiQueue() {
synchronized (queue){
return new PaxiQueue(new Date(),queue.size(),queue.peek());
}
}
@Override
public void clearQueue() {
synchronized (queue){
queue.clear();
}
}
}
複製代碼
其中的PaxiQueue是本身定義的一個對象
public class PaxiQueue {
private final Date date;
private final int size;
private final String head;
@ConstructorProperties({"date","size","head"})
public PaxiQueue(Date date, int size, String head) {
this.date = date;
this.size = size;
this.head = head;
}
public Date getDate() {
return date;
}
public String getHead() {
return head;
}
public int getSize() {
return size;
}
}
複製代碼
Agent的實現爲
public class MyAgent {
public static void main(String[] args) {
//1:獲取平臺已經建立並初始化的MBeanServer,沒有就經過MBeanServerFactory.createMBeanServer()建立
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
try {
ObjectName name = new ObjectName("main.jmx:type=PaxiQ");
Queue<String> queue = new ArrayBlockingQueue<String>(10);
queue.add("r-1");
queue.add("r-2");
queue.add("r-3");
PaxiQ mxbean = new PaxiQ(queue);
//3:註冊MBean
mbs.registerMBean(mxbean,name);
System.out.println("wait for incoming request");
Thread.sleep(Long.MAX_VALUE);
} catch (MalformedObjectNameException e) {
e.printStackTrace();
} catch (NotCompliantMBeanException e) {
e.printStackTrace();
} catch (InstanceAlreadyExistsException e) {
e.printStackTrace();
} catch (MBeanRegistrationException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
複製代碼
啓動後運行jconsole
能夠看到自定義的屬性值爲CompositeDataSupport,雙擊它能夠看到等他的內容: 可是若是PaxiQMXBean是一個MBean,即名字是PaxiQMBean,這個時候經過jconsole是沒法找到的。JMX client代碼
public class PaxiClient {
public static void main(String[] args) {
System.out.println("create RMI client");
try {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
JMXConnector jmxConnector = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
System.out.println("domains");
String[] domains= mBeanServerConnection.getDomains();
Arrays.sort(domains);
for (String domain:domains){
System.out.println(domain);
}
System.out.println("domain:"+mBeanServerConnection.getDefaultDomain());
System.out.println("MBean count:"+mBeanServerConnection.getMBeanCount());
Set<ObjectName> names = new TreeSet<ObjectName>(mBeanServerConnection.queryNames(null,null));
for (ObjectName name:names){
System.out.println("objectname:"+name);
}
ObjectName mbeanName = new ObjectName("main.jmx:type=Paxi");
PaxiMBean mbeanProxy = JMX.newMBeanProxy(mBeanServerConnection,mbeanName,PaxiMBean.class,true);
System.out.println("add notification listener..");
// 自定義消息的監聽
PaxiClientListener listener = new PaxiClientListener();
mBeanServerConnection.addNotificationListener(mbeanName,listener,null,null);
mbeanProxy.setName("new name");
System.out.println("wait notifacaion");
TimeUnit.SECONDS.sleep(2);
System.out.println(mbeanProxy.getName());
mbeanProxy.sayHi();
TimeUnit.SECONDS.sleep(10);
jmxConnector.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (MalformedObjectNameException e) {
e.printStackTrace();
} catch (InstanceNotFoundException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
複製代碼
listener
public class PaxiClientListener implements NotificationListener{
@Override
public void handleNotification(Notification notification, Object handback) {
System.out.println("r notification");
System.out.println("class:"+notification.getClass().getName());
System.out.println("Source:"+notification.getSource());
System.out.println("Type:"+notification.getType());
System.out.println("Message:"+notification.getMessage());
if (notification instanceof AttributeChangeNotification){
AttributeChangeNotification n= (AttributeChangeNotification) notification;
System.out.println("attr name:"+n.getAttributeName());
System.out.println("attr type:"+n.getAttributeType());
System.out.println("attr new Value:"+n.getNewValue());
System.out.println("attr old Value:"+n.getOldValue());
}
}
}
複製代碼