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

Java 8环境下获取GCInfo方法及Minecraft服务器/gcinfo命令实现

解决方案:Minecraft服务器/gcinfo命令获取最近GC信息(兼容Java8)

针对你遇到的Java7 GC代码在Java8无法运行,且需要实现Minecraft服务器的/gcinfo命令来触发查询最近一次GC详细信息的需求,这里提供一个不需要监听器、基于JVM标准管理API的兼容实现:

核心实现思路

Java8中可以通过JDK自带的java.lang.management包提供的标准MXBean来获取GC信息,完全替代Java7中可能依赖的非公开API,同时不需要注册GC监听器,只在命令触发时查询最新数据。

完整命令代码实现

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.GcInfo;
import java.util.List;
import java.util.Map;

public class GCInfoCommand implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (!cmd.getName().equalsIgnoreCase("gcinfo")) {
            return false;
        }

        // 获取JVM内存管理Bean
        MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
        List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();

        // 筛选出记录了最近GC信息的收集器(覆盖多收集器场景)
        GcInfo latestGcInfo = null;
        for (GarbageCollectorMXBean bean : gcBeans) {
            GcInfo currentInfo = bean.getLastGcInfo();
            if (currentInfo != null && (latestGcInfo == null || currentInfo.getStartTime() > latestGcInfo.getStartTime())) {
                latestGcInfo = currentInfo;
            }
        }

        if (latestGcInfo == null) {
            sender.sendMessage("§c未查询到最近一次GC的记录,请检查JVM配置是否开启GC信息收集!");
            return true;
        }

        // 转换内存单位为MB,方便管理员阅读
        long maxMemoryMB = memoryBean.getHeapMemoryUsage().getMax() / 1024 / 1024;
        long freeMemoryMB = (memoryBean.getHeapMemoryUsage().getMax() - memoryBean.getHeapMemoryUsage().getUsed()) / 1024 / 1024;
        
        // 计算GC前后的堆内存使用总量
        long memoryBeforeGcMB = latestGcInfo.getMemoryUsageBeforeGc().values().stream()
                .mapToLong(usage -> usage.getUsed())
                .sum() / 1024 / 1024;
        long memoryAfterGcMB = latestGcInfo.getMemoryUsageAfterGc().values().stream()
                .mapToLong(usage -> usage.getUsed())
                .sum() / 1024 / 1024;
        
        // 计算距离上次GC的时间(秒)
        long timeSinceLastGcSec = (System.currentTimeMillis() - latestGcInfo.getEndTime()) / 1000;

        // 发送格式化的消息(使用Minecraft颜色代码)
        sender.sendMessage("§6=== 最近一次GC详情 ===");
        sender.sendMessage("§f最大内存: §a" + maxMemoryMB + " MB");
        sender.sendMessage("§f剩余内存: §a" + freeMemoryMB + " MB");
        sender.sendMessage("§fGC后已用内存: §a" + memoryAfterGcMB + " MB");
        sender.sendMessage("§fGC前已用内存: §c" + memoryBeforeGcMB + " MB");
        sender.sendMessage("§f距离上次GC时长: §e" + timeSinceLastGcSec + " 秒");

        return true;
    }
}

配置与注意事项

  1. 注册命令到插件:在你的plugin.yml中添加命令配置,确保命令能被Minecraft识别:
name: GCInfoTool
main: com.yourpluginpackage.GCInfoPlugin
version: 1.0
commands:
  gcinfo:
    description: 查询最近一次JVM垃圾回收的详细信息
    usage: /<command>
    permission: gcinfo.admin
    permission-message: §c你没有权限执行此命令!
  1. 权限控制:配置gcinfo.admin权限,只允许服务器管理员或OP使用该命令,避免普通玩家滥用。
  2. JVM兼容性:代码基于JDK标准API,兼容Java8及以上版本,不需要依赖任何非公开的Sun/Oracle API,彻底解决Java7到Java8的兼容问题。
  3. 空值处理:如果JVM未开启GC信息收集(比如某些极端优化配置),代码会返回友好提示,避免插件报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 18:49:08