Java使用HotSpotVirtualMachine和JMXServiceURL获取JVM进程的内存信息

这个Java类展示了如何通过JMX(Java Management Extensions)连接到指定PID的JVM,获取并打印内存池的详细信息,包括堆内存使用情况、堆 histo 数据以及jstack信息。通过加载JMX代理并获取本地连接地址,可以实现远程监控Java应用的内存状态。
摘要由CSDN通过智能技术生成
package com.jvm;

import com.sun.tools.attach.VirtualMachine;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import sun.tools.attach.*;

import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.File;
import java.io.InputStream;
import java.lang.management.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

public class JvmUtils {
	/*  获取 jvm 信息 */
    public static String attachJmx(String pid){
        VirtualMachine virtualMachine = null ;
        try{
            virtualMachine = VirtualMachine.attach(pid) ;
            HotSpotVirtualMachine machine = (HotSpotVirtualMachine) virtualMachine ;
            String javaHome = virtualMachine.getSystemProperties().getProperty("java.home");

            String jmxAgent = javaHome + File.separator + "lib" + File.separator + "management-agent.jar";
            virtualMachine.loadAgent(jmxAgent, "com.sun.management.jmxremote");
            Properties properties = virtualMachine.getAgentProperties();
            String address = (String) properties.get("com.sun.management.jmxremote.localConnectorAddress");
            virtualMachine.detach();
            return address;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null ;
    }
	/* 获取 jstack 堆信息*/
    public static String getStack(String pid){
        VirtualMachine virtualMachine = null ;
        InputStream is = null ;
        try{
            virtualMachine = VirtualMachine.attach(pid) ;
            HotSpotVirtualMachine machine = (HotSpotVirtualMachine) virtualMachine ;
            is = machine.remoteDataDump(new String[]{});
            return IOUtils.toString(is , StandardCharsets.UTF_8.name());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            IOUtils.closeQuietly(is);
        }
        return null ;
    }
	/*  获取 heapHisto 信息 */
    public static String heapHisto(String pid){
        VirtualMachine virtualMachine = null ;
        InputStream is = null ;
        try{
            virtualMachine = VirtualMachine.attach(pid) ;
            HotSpotVirtualMachine machine = (HotSpotVirtualMachine) virtualMachine ;
            is = machine.heapHisto(new String[]{});
            return IOUtils.toString(is , StandardCharsets.UTF_8.name());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            IOUtils.closeQuietly(is);
        }
        return null ;
    }
	/* 获取各种内存信息,  jmap -heap pid */
    public static void getMemory(String pid ){
        String address = attachJmx(pid);
        try {
            JMXServiceURL target = new JMXServiceURL(address);
            final JMXConnector connector = JMXConnectorFactory.connect(target);
            final MBeanServerConnection mbsc = connector.getMBeanServerConnection();

            TimeUnit.SECONDS.sleep(1);

            List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getPlatformMXBeans(mbsc , MemoryPoolMXBean.class);
            for (MemoryPoolMXBean memoryPoolMXBean : memoryPoolMXBeans) {
                String name = memoryPoolMXBean.getName();
                String[] memoryManagerNames = memoryPoolMXBean.getMemoryManagerNames();
                MemoryType type = memoryPoolMXBean.getType();
                MemoryUsage usage = memoryPoolMXBean.getUsage();
                MemoryUsage peakUsage = memoryPoolMXBean.getPeakUsage();

                System.out.println(name + ":");
                System.out.println("    managers: " + StringUtils.join(memoryManagerNames , " , "));
                System.out.println("    type: " + type.toString());
                System.out.print("    usage: " + usage.toString());
                System.out.println("    Percentage: " + ((double) usage.getUsed() / usage.getCommitted() ) );
                System.out.println("    peakUsage: "  +peakUsage.toString());

                System.out.println("");
            }

        }catch (Exception e){
            e.printStackTrace();
        }


    }

    public static void main(String[] args) {
       // 传递进程ID
        getMemory("3112" );
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值