You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在独立Java应用中监控Minecraft服务器(另一JVM)的资源

监控外部Minecraft服务器JVM的CPU与内存使用率(基于MXBeans)

前置准备

  • 确保项目类路径包含JDK自带的tools.jar(位于JDK安装目录的lib文件夹下),因为要用到JVM Attach API。
  • 先获取Minecraft服务器的进程PID:Windows用tasklist命令,Linux/macOS用jps命令,找到对应Java进程的ID。

核心实现代码

1. 连接到目标JVM

通过Attach API建立与Minecraft服务器JVM的连接,这是获取远程MXBeans的基础:

import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import java.io.IOException;
import java.util.List;

// 根据进程名称匹配获取目标PID(比如Minecraft服务器进程名通常包含minecraft_server.jar)
private static String getTargetPid(String processKeyword) {
    List<VirtualMachineDescriptor> runningVms = VirtualMachine.list();
    for (VirtualMachineDescriptor vmd : runningVms) {
        if (vmd.displayName().contains(processKeyword)) {
            return vmd.id();
        }
    }
    return null;
}

// 连接到目标JVM
private static VirtualMachine connectToTarget(String pid) throws IOException, AttachNotSupportedException {
    return VirtualMachine.attach(pid);
}

2. 内存使用率监控与进度条更新

利用MemoryMXBean获取堆内存使用情况,计算使用率后更新JProgressBar:

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import javax.swing.JProgressBar;

// 更新内存监控进度条
public static void refreshMemoryStatus(VirtualMachine targetVm, JProgressBar memoryBar) throws Exception {
    // 获取远程JVM的MemoryMXBean代理
    MemoryMXBean memoryBean = ManagementFactory.newPlatformMXBeanProxy(
            targetVm.getConnectorAddress(),
            MemoryMXBean.class.getName(),
            true
    );

    MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
    long used = heapUsage.getUsed();
    long max = heapUsage.getMax();
    int usagePercent = (int) ((used * 100) / max);

    // Swing组件必须在EDT线程更新
    javax.swing.SwingUtilities.invokeLater(() -> {
        memoryBar.setValue(usagePercent);
        memoryBar.setString(String.format("内存: %d%%", usagePercent));
        memoryBar.setStringPainted(true);
    });
}

3. CPU使用率监控与进度条更新

通过OperatingSystemMXBean获取目标进程的CPU负载,转换为百分比后更新进度条:

import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import javax.swing.JProgressBar;

// 更新CPU监控进度条
public static void refreshCpuStatus(VirtualMachine targetVm, JProgressBar cpuBar) throws Exception {
    OperatingSystemMXBean osBean = ManagementFactory.newPlatformMXBeanProxy(
            targetVm.getConnectorAddress(),
            OperatingSystemMXBean.class.getName(),
            true
    );

    // getProcessCpuLoad返回0.0-1.0的数值,转为百分比
    double cpuLoad = osBean.getProcessCpuLoad();
    int usagePercent = (int) (cpuLoad * 100);
    // 处理初始未收集到数据时的-1值
    usagePercent = Math.max(usagePercent, 0);

    javax.swing.SwingUtilities.invokeLater(() -> {
        cpuBar.setValue(usagePercent);
        cpuBar.setString(String.format("CPU: %d%%", usagePercent));
        cpuBar.setStringPainted(true);
    });
}

4. 定时刷新监控数据

用Swing Timer实现每秒自动刷新监控数据:

import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

// 启动定时监控任务
public static void startMonitoring(String targetPid, JProgressBar cpuBar, JProgressBar memoryBar) {
    try {
        VirtualMachine targetVm = connectToTarget(targetPid);

        // 每1000毫秒(1秒)刷新一次
        Timer timer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    refreshCpuStatus(targetVm, cpuBar);
                    refreshMemoryStatus(targetVm, memoryBar);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    // 目标JVM断开连接时停止定时器
                    ((Timer) e.getSource()).stop();
                }
            }
        });
        timer.start();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

5. 整合到你的GUI中

假设你已有包含两个JProgressBar的窗口,在初始化时启动监控:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import java.awt.GridLayout;

public class McServerMonitor extends JFrame {
    private JProgressBar cpuBar;
    private JProgressBar memoryBar;

    public McServerMonitor() {
        setTitle("Minecraft服务器监控");
        setSize(400, 150);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel panel = new JPanel(new GridLayout(2, 1));
        cpuBar = new JProgressBar();
        memoryBar = new JProgressBar();
        panel.add(cpuBar);
        panel.add(memoryBar);
        add(panel);

        // 替换为你的Minecraft服务器进程关键词或直接写PID
        String targetPid = getTargetPid("minecraft_server.jar");
        if (targetPid != null) {
            startMonitoring(targetPid, cpuBar, memoryBar);
        } else {
            System.out.println("未找到目标Minecraft服务器进程");
        }
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(() -> {
            new McServerMonitor().setVisible(true);
        });
    }

    // 把前面的getTargetPid、connectToTarget、refreshMemoryStatus、refreshCpuStatus、startMonitoring方法复制到这里
}

关键注意事项

  • 权限要求:运行监控程序的用户需与Minecraft服务器进程拥有相同权限,否则Attach API无法建立连接。
  • tools.jar依赖:如果用Maven,需手动将tools.jar添加到项目依赖;普通项目直接将其加入类路径即可。
  • 版本兼容:尽量保证监控程序与Minecraft服务器的JDK版本一致,避免API兼容性问题。
  • 异常处理:实际使用中可添加进程断开后的重连逻辑,提升稳定性。

内容的提问来源于stack exchange,提问作者Mute

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 02:27:45