下列类演示如何连接到正在运行的JVM并建立JMX连接,并在必要时加载JMX代理。它将使用MemoryMXBean打印系统属性(无需JMX即可通过JVM连接工作)和内存使用情况。使用其他MXBean类型进行扩展以打印其他统计信息很容易。
请注意,在Java 9之前,您必须将
tools.jarJDK的手动添加到类路径。在模块化软件中,您必须向
jdk.attach模块添加依赖项。
import static java.lang.management.ManagementFactory.MEMORY_MXBEAN_NAME;import static java.lang.management.ManagementFactory.newPlatformMXBeanProxy;import java.io.*;import java.lang.management.MemoryMXBean;import java.lang.management.MemoryUsage;import java.util.*;import javax.management.MBeanServerConnection;import javax.management.remote.JMXConnector;import javax.management.remote.JMXConnectorFactory;import javax.management.remote.JMXServiceURL;import com.sun.tools.attach.*;public class CmdLineTool{ static final String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress"; public static void main(String[] args) { if(args.length!=1) System.err.println("Usage: java CmdLineTool <pid>"); else if(printStats(args[0])) return; System.out.println("Currently running"); for(VirtualMachineDescriptor vmd:VirtualMachine.list()) System.out.println(vmd.id()+"t"+vmd.displayName()); } private static boolean printStats(String id) { try { VirtualMachine vm=VirtualMachine.attach(id); System.out.println("Connected to "+vm.id()); System.out.println("System Properties:"); for(Map.Entry<?,?> en:vm.getSystemProperties().entrySet()) System.out.println("t"+en.getKey()+" = "+en.getValue()); System.out.println(); try { MBeanServerConnection sc=connect(vm); MemoryMXBean memoryMXBean = newPlatformMXBeanProxy(sc, MEMORY_MXBEAN_NAME, MemoryMXBean.class); getRamInfoHtml(memoryMXBean); } catch(IOException ex) { System.out.println("JMX: "+ex); } vm.detach(); return true; } catch(AttachNotSupportedException | IOException ex) { ex.printStackTrace(); } return false; } // requires Java 8, alternative below the pre static MBeanServerConnection connect(VirtualMachine vm) throws IOException { String connectorAddress = vm.startLocalManagementAgent(); JMXConnector c=JMXConnectorFactory.connect(new JMXServiceURL(connectorAddress)); return c.getMBeanServerConnection(); } static void getRamInfoHtml(MemoryMXBean memoryMXBean) { System.out.print("Heap:t"); MemoryUsage mu=memoryMXBean.getHeapMemoryUsage(); System.out.println( "allocated "+mu.getCommitted()+", used "+mu.getUsed()+", max "+mu.getMax()); System.out.print("Non-Heap:t"); mu=memoryMXBean.getNonHeapMemoryUsage(); System.out.println( "allocated "+mu.getCommitted()+", used "+mu.getUsed()+", max "+mu.getMax()); System.out.println( "Pending Finalizations: "+memoryMXBean.getObjectPendingFinalizationCount()); }}
connect上述解决方案的方法需要Java8。较旧的Java版本的替代方案如下所示:
static MBeanServerConnection connect(VirtualMachine vm) throws IOException{ String connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); if(connectorAddress == null) { System.out.println("loading agent"); Properties props = vm.getSystemProperties(); String home = props.getProperty("java.home"); String agent = home+File.separator+"lib"+File.separator+"management-agent.jar"; try { vm.loadAgent(agent); } catch (AgentLoadException|AgentInitializationException ex) { throw new IOException(ex); } connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); while(connectorAddress==null) try { Thread.sleep(1000); connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); } catch(InterruptedException ex){} } JMXConnector c=JMXConnectorFactory.connect(new JMXServiceURL(connectorAddress)); return c.getMBeanServerConnection();}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)