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

Jar文件未显示全部属性:获取运行中Jar堆内存信息失败

解决获取运行中Jar堆内存信息的问题

哦,我懂你碰到的麻烦了——用VirtualMachine.getAgentProperties()确实拿不到堆内存相关的数据,这完全是因为这个方法的定位就不是用来获取运行时内存指标的😉

为什么getAgentProperties()拿不到堆内存数据?

getAgentProperties()返回的是和JVM agent相关的系统属性集合,比如agent的启动参数、加载路径这类配置信息,和JVM运行时的内存使用情况根本不是一个范畴的东西,所以堆内存相关的属性自然会返回null。

正确获取堆内存信息的方法

要获取JVM的堆内存使用情况,你需要通过VirtualMachine拿到MBeanServer连接,然后借助JMX的MemoryMXBean来获取详细的内存指标。下面是具体的代码示例:

import com.sun.tools.attach.VirtualMachine;
import javax.management.MBeanServerConnection;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;

public class JarMemoryMonitor {
    public static void main(String[] args) throws Exception {
        // 替换成你的目标Jar进程ID
        String pid = "your-process-id";
        VirtualMachine vm = VirtualMachine.attach(pid);
        
        // 获取MBeanServer连接,这是访问JVM运行时指标的关键
        MBeanServerConnection conn = vm.getMBeanServerConnection();
        
        // 通过代理获取MemoryMXBean实例
        MemoryMXBean memoryBean = ManagementFactory.newPlatformMXBeanProxy(
            conn,
            ManagementFactory.MEMORY_MXBEAN_NAME,
            MemoryMXBean.class
        );
        
        // 获取堆内存使用详情
        MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
        System.out.println("当前堆内存已用: " + (heapUsage.getUsed() / 1024 / 1024) + " MB");
        System.out.println("当前堆内存已分配: " + (heapUsage.getCommitted() / 1024 / 1024) + " MB");
        System.out.println("堆内存最大值: " + (heapUsage.getMax() / 1024 / 1024) + " MB");
        
        // 如果需要非堆内存信息,也可以用下面的代码
        MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();
        System.out.println("非堆内存已用: " + (nonHeapUsage.getUsed() / 1024 / 1024) + " MB");
        
        vm.detach();
    }
}

额外扩展:获取更细分的内存池信息

如果你需要了解新生代、老年代这类具体内存池的使用情况,可以获取MemoryPoolMXBean的列表,示例代码如下:

import java.lang.management.MemoryPoolMXBean;
import java.util.List;

// ... 前面的代码不变

List<MemoryPoolMXBean> poolBeans = ManagementFactory.newPlatformMXBeanProxy(
    conn,
    ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE,
    List.class
);

for (MemoryPoolMXBean poolBean : poolBeans) {
    MemoryUsage usage = poolBean.getUsage();
    System.out.println("\n内存池名称: " + poolBean.getName());
    System.out.println("已用内存: " + (usage.getUsed() / 1024 / 1024) + " MB");
    System.out.println("已分配内存: " + (usage.getCommitted() / 1024 / 1024) + " MB");
}

注意事项

  • 运行监控程序的用户需要和目标Jar进程拥有相同的权限,否则VirtualMachine.attach()可能会抛出权限异常。
  • 确保监控程序使用的JDK版本和目标Jar进程的JDK版本兼容,避免出现版本不匹配的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:29:58