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

发布于 2024-10-10 09:43:50 字数 273 浏览 0 评论 0原文

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

是否有可用于识别本地运行的 JVM 的服务 URL?

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

If you set the "com.sun.management.jmxremote" system property when you start a JVM, you can run jconsole or visualvm and connect to that local mBeanServer. I want to do the same thing they are doing but can't figure out how.

Is there a service URL you can use to identify a locally running JVM?

I know I could do this by setting up a jmxmp or rmi listener on a specific port and then connecting to that port, but I don't want to do that because it means I have to manage the ports and know which port goes to which jvm (we run multiple jvms on the same server).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

静谧幽蓝 2024-10-17 09:43:50

感谢尼古拉斯和斯科特的发帖和讨论。能够根据该信息和一些试验和错误将其拼凑在一起。

共享,这样其他人就不必做同样的跑腿工作。这将附加到 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;
    }
}

Thanks to Nicholas and Scott for the post and discussion. Was able to piece this together based on that info and some trial and error.

Sharing so others don't have to do the same leg work. This will attach to a JVM and get its memory usage.

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;
    }
}
眼泪都笑了 2024-10-17 09:43:50

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

//尼古拉斯

You need the Attach API. It will locate running [Attach API capable] JVMs on the same host and return meta-data on each as well as enable a JMXConnector. It's basically what you see when you start JConsole and the connect menu displays running JVMs, including Java 1.6+ instances that were not started with any special JMX command line directives.

//Nicholas

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文