4

JVM の起動時に「com.sun.management.jmxremote」システム プロパティを設定すると、jconsole または visualvm を実行して、そのローカル mBeanServer に接続できます。彼らと同じことをしたいのですが、方法がわかりません。

ローカルで実行中の JVM を識別するために使用できるサービス URL はありますか?

特定のポートにjmxmpまたはrmiリスナーを設定してからそのポートに接続することでこれを行うことができることは知っていますが、ポートを管理し、どのポートがどのポートに接続するかを知る必要があるため、そうしたくありませんjvm (同じサーバーで複数の jvm を実行します)。

4

2 に答える 2

7

投稿と議論をしてくれた 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;
    }
}
于 2012-10-29T06:59:22.573 に答える
1

Attach APIが必要です。同じホスト上で実行中の [Attach API 対応] JVM を見つけ、それぞれのメタデータを返し、JMXConnector を有効にします。これは基本的に、JConsole を起動したときに表示されるものであり、接続メニューには、特別な JMX コマンド ライン ディレクティブで起動されていない Java 1.6+ インスタンスを含む、実行中の JVM が表示されます。

//ニコラス

于 2010-12-31T10:39:19.373 に答える