对于类项目,我想实现一个Java应用程序,该应用程序连接到本地JVM并收集统计信息,如堆使用情况,线程数,加载的类等。我在线搜索对于一个API,内置的第三方,这将允许我这样做,但我迄今没有成功。API从运行的JVM收集统计信息
有谁知道一个API,可以让我连接到正在运行的JVM并收集统计信息吗?
对于类项目,我想实现一个Java应用程序,该应用程序连接到本地JVM并收集统计信息,如堆使用情况,线程数,加载的类等。我在线搜索对于一个API,内置的第三方,这将允许我这样做,但我迄今没有成功。API从运行的JVM收集统计信息
有谁知道一个API,可以让我连接到正在运行的JVM并收集统计信息吗?
以下类演示如何连接到正在运行的JVM并建立JMX连接,并根据需要加载JMX代理。它将使用MemoryMXBean打印系统属性(这通过JVM连接工作,不需要JMX)和内存使用情况。使用其他MXBean类型扩展可以轻松地打印其他统计信息。
请注意,您必须手动将JDK的tools.jar
添加到类路径中。
import static java.lang.management.ManagementFactory.MEMORY_MXBEAN_NAME;
import static java.lang.management.ManagementFactory.newPlatformMXBeanProxy;
import java.io.File;
import java.io.IOException;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.util.Map;
import java.util.Properties;
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);
System.out.println();
getRamInfoHtml(memoryMXBean);
} catch(AgentLoadException | AgentInitializationException ex)
{
System.out.println("JMX: "+ex);
}
vm.detach();
return true;
} catch(AttachNotSupportedException | IOException ex)
{
ex.printStackTrace();
}
return false;
}
static MBeanServerConnection connect(VirtualMachine vm)
throws AgentLoadException, AgentInitializationException, 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";
vm.loadAgent(agent);
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();
}
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());
}
}
如果你想从一个正在运行的JVM的统计数据,你可以使用VisualVM,它随JDK的本地API。它为jvm上的所有正在运行的进程提供统计信息。
VisualVM通过Java API公开了它的一些功能。请注意,这些是在com.sun.tools.*
包中,而不是通常的java.*
或javax.*
包。
有关如何使用这些API的更多信息,请参见Getting Started Extending VisualVM。
JMX不是用于这个目的吗? – RandomQuestion
http://stackoverflow.com/questions/856881/how-to-activate-jmx-on-my-jvm-for-access-with-jconsole – dnault
这可能也有帮助。 http://docs.oracle.com/javase/7/docs/technotes/guides/management/agent.html – RandomQuestion