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("------------------------------------------------------------------------------------------------------");
}
}
效果图