Java之JMX获取应用进程CPU/内存使用率,监控GC回收

JMX是什么?

JMX全称是Java Management Extensions。 Java 管理扩展。 它提供了对Java应用程序和JVM的监控和管理功能。

采集应用进程CPU使用率

static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void monitorCPU() {
        try {
            // 操作系统 MXBean
            OperatingSystemMXBean mxBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
            // CPU核心数
            int processors = mxBean.getAvailableProcessors();
            // 运行时 MXBean
            RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
            // 基于当前时间, 采集应用运行时长, 单位毫秒, 转换成纳秒,
            long prevUpTime = runtimeMXBean.getUptime() * 1000000;
            // 基于当前时间, 采集应用进程CPU运行时长, 单位毫秒
            long prevProcessCpuTime = mxBean.getProcessCpuTime() / processors;
            while (true) {
                // 每隔一秒采集一次
                TimeUnit.SECONDS.sleep(1);
                // 基于当前时间, 采集应用运行时长
                long processCpuTime = mxBean.getProcessCpuTime() / processors;
                // 基于当前时间, 采集应用进程CPU运行时长
                long upTime = runtimeMXBean.getUptime() * 1000000;
                String date = format.format(new Date());
                // 当前运行时长减去上一次的运行时长, 得到采样间隔
                long upTimeDiff = upTime - prevUpTime;
                // 当前应用进程运行时长减去上一次的运行时长, 得到采样间隔
                long processTimeDiff = processCpuTime - prevProcessCpuTime;
                /**
                 * 计算应用进程CPU使用率,
                 * 计算方式: CPU运行时间 / 总运行时间
                 * 例如: upTimeDiff = 1秒, processTimeDiff = 0.2秒, 则应用进程CPU使用率为 20%
                 *
                 * 也就是: 应用进程CPU使用时长, 在一段时间内的使用占比
                 */
                float processCPUUsage = Math.min((float) (processTimeDiff * 100) / (float) upTimeDiff, 100);

                // 将当前采样时间设置为上一次
                prevUpTime = upTime;
                prevProcessCpuTime = processCpuTime;

                System.out.println(date + " -进程CPU- " + String.format("%.2f", processCPUUsage) + "%");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

效果图

在这里插入图片描述

第二种方式,需要jdk1.8才支持,而且数据不咋的准确。

OperatingSystemMXBean mxBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
System.out.println(" -进程CPU- " + String.format("%.2f", mxBean.getProcessCpuLoad() * 100) + "%");
System.out.println(" -系统CPU- " + String.format("%.2f", mxBean.getSystemCpuLoad() * 100) + "%\n");

采集应用进程内存的使用

static NumberFormat fmtI = new DecimalFormat("###,###", new DecimalFormatSymbols(Locale.ENGLISH));
public void monitorMemory() {
        List<MemoryPoolMXBean> memoryBeans = ManagementFactory.getMemoryPoolMXBeans();
        while (true) {
            for (MemoryPoolMXBean mxBean : memoryBeans) {
                StringBuilder sb = new StringBuilder();
                MemoryUsage usage = mxBean.getUsage();
                sb.append("内存模型: [")
                        .append(mxBean.getType().name())
                        .append("], 内存空间名称: [")
                        .append(mxBean.getName())
                        .append("], 初始化[")
                        .append(bytesToMB(usage.getInit()))
                        .append("], 已使用[")
                        .append(bytesToMB(usage.getUsed()))
                        .append("], 可使用[")
                        .append(bytesToMB(usage.getCommitted()))
                        .append("], 最大[")
                        .append(bytesToMB(usage.getMax()))
                        .append("]");
                System.out.println(sb);
            }
            System.out.println("------------------------------------------------------------------------------------------------------");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (Exception e) {
            }
        }
    }

效果图

在这里插入图片描述
监控应用进程GC

public void monitorGC() {
        /**
         * 以JDK 1.8默认的GC回收器为例: Parallel Scavenge GC
         * gcMXBeans[0] PS Scavenge     监控新生代垃圾回收
         * gcMXBeans[1] PS MarkSweep    监控老年代/元空间/堆外内存急其他
         */
        List<GarbageCollectorMXBean> gcMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
        GCNotificationListener listener = new GCNotificationListener();
        gcMXBeans.forEach(gcmx -> {
            NotificationEmitter emitter = (NotificationEmitter) gcmx;
            emitter.addNotificationListener(listener, null, null);
        });
    }

    private class GCNotificationListener implements NotificationListener {
        @Override
        public void handleNotification(Notification notification, Object handback) {
            CompositeData cd = (CompositeData) notification.getUserData();
            GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd);
            GcInfo gcInfo = info.getGcInfo();

            Map<String, MemoryUsage> memoryUsageBeforeGc = gcInfo.getMemoryUsageBeforeGc();
            Map<String, MemoryUsage> memoryUsageAfterGc = gcInfo.getMemoryUsageAfterGc();

            System.out.println("GC前 - 内存情况 " + memoryUsageBeforeGc);
            System.out.println("GC后 - 内存情况 " + memoryUsageAfterGc);

            StringBuilder sb = new StringBuilder();
            sb.append("第[")
                    .append(gcInfo.getId())
                    .append("]次")
                    .append("GC, 耗时: [")
                    .append(gcInfo.getDuration())
                    .append("]毫秒, GC名称: [")
                    .append(info.getGcName())
                    .append("], GC原因: [")
                    .append(info.getGcCause())
                    .append("]");
            System.out.println(sb.toString());
            System.out.println("------------------------------------------------------------------------------------------------------");
        }
    }

效果图

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,以下是一个通过JMX获取服务器CPU内存,磁盘,网络信息的Java工具类的示例代码: ```java import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.util.ArrayList; import java.util.List; import javax.management.AttributeNotFoundException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.ReflectionException; public class ServerMonitoringUtil { private static final String OS_MXBEAN_NAME = "java.lang:type=OperatingSystem"; private static final String MEMORY_MXBEAN_NAME = "java.lang:type=Memory"; private static final String CLASS_LOADING_MXBEAN_NAME = "java.lang:type=ClassLoading"; private static final String RUNTIME_MXBEAN_NAME = "java.lang:type=Runtime"; private static final String THREAD_MXBEAN_NAME = "java.lang:type=Threading"; private static final String GARABAGE_COLLECTOR_MXBEAN_NAME = "java.lang:type=GarbageCollector,*"; private static final String NETWORK_INTERFACE_MXBEAN_NAME = "java.lang:type=OperatingSystem"; private MBeanServerConnection mbsc; public ServerMonitoringUtil(MBeanServerConnection mbsc) { this.mbsc = mbsc; } public double getCpuUsage() throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException { OperatingSystemMXBean osMxBean = ManagementFactory.newPlatformMXBeanProxy(mbsc, OS_MXBEAN_NAME, OperatingSystemMXBean.class); return osMxBean.getSystemCpuLoad(); } public long getMemoryUsed() throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException { ObjectName memoryMxBeanName = new ObjectName(MEMORY_MXBEAN_NAME); long used = (Long) mbsc.getAttribute(memoryMxBeanName, "HeapMemoryUsage.used"); used += (Long) mbsc.getAttribute(memoryMxBeanName, "NonHeapMemoryUsage.used"); return used; } public long getMemoryMax() throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException { ObjectName memoryMxBeanName = new ObjectName(MEMORY_MXBEAN_NAME); long max = (Long) mbsc.getAttribute(memoryMxBeanName, "HeapMemoryUsage.max"); max += (Long) mbsc.getAttribute(memoryMxBeanName, "NonHeapMemoryUsage.max"); return max; } public double getClassLoadingRate() throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException { ObjectName classLoadingMxBeanName = new ObjectName(CLASS_LOADING_MXBEAN_NAME); long loadedCount = (Long) mbsc.getAttribute(classLoadingMxBeanName, "LoadedClassCount"); long totalLoadedCount = (Long) mbsc.getAttribute(classLoadingMxBeanName, "TotalLoadedClassCount"); long unloadedCount = (Long) mbsc.getAttribute(classLoadingMxBeanName, "UnloadedClassCount"); return (double) loadedCount / totalLoadedCount; } public long getThreadCount() throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException { ObjectName threadMxBeanName = new ObjectName(THREAD_MXBEAN_NAME); return (Long) mbsc.getAttribute(threadMxBeanName, "ThreadCount"); } public long getGarbageCollectionTime() throws MalformedObjectNameException, AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException { long gcTime = 0; List<ObjectName> gcMxBeanNames = new ArrayList<ObjectName>(); gcMxBeanNames.addAll(mbsc.queryNames(new ObjectName(GARABAGE_COLLECTOR_MXBEAN_NAME), null)); for (ObjectName gcMxBeanName : gcMxBeanNames) { gcTime += (Long) mbsc.getAttribute(gcMxBeanName, "CollectionTime"); } return gcTime; } public long getDiskUsed() { // TODO: Implement disk usage monitoring return 0; } public long getNetworkInboundBytes() { // TODO: Implement network inbound bytes monitoring return 0; } public long getNetworkOutboundBytes() { // TODO: Implement network outbound bytes monitoring return 0; } } ``` 该工具类实现了获取CPU使用率内存使用情况、类加载速率、线程数、垃圾回收时间等信息的方法,同时也提供了获取磁盘使用情况、网络流量等信息的桩函数,需要根据实际情况进行实现。在使用该工具类时,需要传入一个已经连接到目标服务器的MBeanServerConnection对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Me_Liu_Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值