有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何连接到另一个本地进程中的mBeanServer?

如果在启动JVM时设置“com.sun.management.jmxremote”系统属性,则可以运行jconsole或visualvm并连接到该本地mBeanServer。我想做和他们一样的事情,但不知道怎么做

是否有一个服务URL可用于标识本地运行的JVM

我知道我可以通过在特定端口上设置jmxmp或rmi侦听器,然后连接到该端口来实现这一点,但我不想这样做,因为这意味着我必须管理端口并知道哪个端口连接到哪个jvm(我们在同一台服务器上运行多个jvm)


共 (2) 个答案

  1. # 1 楼答案

    感谢Nicholas和Scott的帖子和讨论。基于这些信息和一些尝试和错误,我们能够将这些信息拼凑在一起

    分享,这样其他人就不必做同样的腿部工作。这将连接到JVM并获取其内存使用情况

    import com.sun.tools.attach.VirtualMachine;
    import com.sun.tools.attach.VirtualMachineDescriptor;
    import com.sun.tools.attach.spi.AttachProvider;
    
    import javax.management.MBeanServerConnection;
    import javax.management.ObjectName;
    import javax.management.openmbean.CompositeData;
    import javax.management.remote.JMXConnector;
    import javax.management.remote.JMXConnectorFactory;
    import javax.management.remote.JMXServiceURL;
    
    public class AttachFun {
    
        public static void main(String[] args) throws Exception {
            final AttachProvider attachProvider = AttachProvider.providers().get(0);
    
            VirtualMachineDescriptor descriptor = null;
            for (VirtualMachineDescriptor virtualMachineDescriptor : attachProvider.listVirtualMachines()) {
                if (pickThisOne(virtualMachineDescriptor)) {
                    descriptor = virtualMachineDescriptor;
                    break;
                }
            }
    
            if (descriptor == null) throw new RuntimeException("You didn't pick one");
    
            final VirtualMachine virtualMachine = attachProvider.attachVirtualMachine(descriptor);
            virtualMachine.loadAgent("/System/Library/Frameworks/JavaVM.framework/Home/lib/management-agent.jar", "com.sun.management.jmxremote");
            final Object portObject = virtualMachine.getAgentProperties().get("com.sun.management.jmxremote.localConnectorAddress");
    
            final JMXServiceURL target = new JMXServiceURL(portObject + "");
            final JMXConnector connector = JMXConnectorFactory.connect(target);
            final MBeanServerConnection remote = connector.getMBeanServerConnection();
    
            final ObjectName memory = new ObjectName("java.lang:type=Memory");
            CompositeData cd = (CompositeData) remote.getAttribute(memory, "HeapMemoryUsage");
    
            final Long used = (Long) cd.get("used");
            System.out.println(used);
    
        }
    
        private static boolean pickThisOne(VirtualMachineDescriptor virtualMachineDescriptor) {
            // TODO
            return false;
        }
    }
    
  2. # 2 楼答案

    你需要Attach API。它将在同一台主机上找到正在运行的[Attach API capable]JVM,并在每个JVM上返回元数据,同时启用JMXConnector。这基本上是启动JConsole时看到的,连接菜单显示正在运行的JVM,包括未使用任何特殊JMX命令行指令启动的Java 1.6+实例

    //尼古拉斯