前文:在实际项目中我们需要观测系统JVM的相关情况。在不接入监控软件的情况下,我们怎么才能可以查看jvm相关参数情况呢。
正文:
我们需要观测的参数包括:记录操作系统内存,记录虚拟机内存,记录堆内存信息,记录垃圾收集信息,记录线程信息。
1、记录操作系统内存
/**
* 记录操作系统内存
* @param baseInfo
* @return
*/
private static String getOSMemoryInfo(String baseInfo) {
int byteToMb = 1024 * 1024;
// 操作系统级内存情况查询
OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
String os = System.getProperty("os.name");
long physicalFree = osmxb.getFreePhysicalMemorySize() / byteToMb;
long physicalTotal = osmxb.getTotalPhysicalMemorySize() / byteToMb;
long physicalUse = physicalTotal - physicalFree;
baseInfo += format("操作系统内存信息", "*");
baseInfo += format("");
baseInfo += format("操作系统的版本:" + os);
baseInfo += format("操作系统内存已使用:" + physicalFree + " MB");
baseInfo += format("操作系统内存剩余:" + physicalUse + " MB");
baseInfo += format("操作系统总内存:" + physicalTotal + " MB");
baseInfo += format("");
return baseInfo;
}
2、记录虚拟机内存
/**
* 记录虚拟机内存
* @param baseInfo
* @return
*/
private static String getJVMMemoryInfo(String baseInfo) {
// 虚拟机级内存情况查询
long vmFree = 0;
long vmUse = 0;
long vmTotal = 0;
long vmMax = 0;
int byteToMb = 1024 * 1024;
Runtime rt = Runtime.getRuntime();
vmTotal = rt.totalMemory() / byteToMb;
vmFree = rt.freeMemory() / byteToMb;
vmMax = rt.maxMemory() / byteToMb;
vmUse = vmTotal - vmFree;
baseInfo += format("JVM内存信息", "*");
baseInfo += format("");
baseInfo += format("JVM内存已用的空间为:" + vmUse + " MB");
baseInfo += format("" + "JVM内存的空闲空间为:" + vmFree + " MB");
baseInfo += format("" + "JVM总内总存空间为:" + vmTotal + " MB");
baseInfo += format("" + "JVM总内存最大空间为:" + vmMax + " MB");
baseInfo += format("");
return baseInfo;
}
3、记录堆内存信息
/**
* 记录堆内存信息
* @param baseInfo
* @return
*/
private static String getHeapInfo(String baseInfo) {
int byteToMb = 1024 * 1024;
MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();
MemoryUsage usage = memorymbean.getHeapMemoryUsage();
baseInfo += format("堆内存信息", "*");
baseInfo += format("");
baseInfo += format("初始堆大小:" + usage.getInit() / byteToMb + "MB");
baseInfo += format("最大值:" + usage.getMax() / byteToMb + "MB");
baseInfo += format("已使用:" + usage.getUsed() / byteToMb + "MB");
baseInfo += format("");
retu
4、记录垃圾收集信息
/**
* 记录垃圾收集信息
* @param baseInfo
* @return
*/
private static String getGCInfo(String baseInfo) {
List<GarbageCollectorMXBean> gcmList = ManagementFactory.getGarbageCollectorMXBeans();
baseInfo += format("垃圾收集信息", "*");
baseInfo += format("");
for (GarbageCollectorMXBean gcm : gcmList) {
baseInfo += format("垃圾收集器名称:" + gcm.getName());
long collectionTime = gcm.getCollectionTime();
long collectionCount = gcm.getCollectionCount();
baseInfo += format("垃圾收集次数:" + collectionCount + " 次,垃圾收集时间:" + collectionTime + "毫秒");
}
baseInfo += format("");
return baseInfo;
}
5、记录线程信息
/**
* 记录线程信息
* @param baseInfo
* @return
*/
private static String getThreadInfo(String baseInfo) {
ThreadMXBean tm = ManagementFactory.getThreadMXBean();
baseInfo += format("线程信息", "*");
baseInfo += format("");
baseInfo += format("线程数:" + tm.getThreadCount());
baseInfo += format("最大线程数:" + tm.getPeakThreadCount());
baseInfo += format("守护线程数:" + tm.getDaemonThreadCount());
baseInfo += format("");
return baseInfo;
}
/**
* 记录JVM情况
*/
@Slf4j
public class JVMObserver {
public static void Observer() {
String configInfo = format("START", "*");
configInfo += format("");
configInfo += format("开始观察JVM: " + DateUtil.now());
configInfo += format("");
// 记录操作系统内存
configInfo = getOSMemoryInfo(configInfo);
// 记录虚拟机内存
configInfo = getJVMMemoryInfo(configInfo);
// 记录堆内存信息
configInfo = getHeapInfo(configInfo);
// 记录垃圾收集信息
configInfo = getGCInfo(configInfo);
// 记录线程信息
configInfo = getThreadInfo(configInfo);
configInfo += format("END", "*");
log.info("configInfo具体信息:{}",configInfo);
}
/**
* 记录操作系统内存
* @param baseInfo
* @return
*/
private static String getOSMemoryInfo(String baseInfo) {
int byteToMb = 1024 * 1024;
// 操作系统级内存情况查询
OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
String os = System.getProperty("os.name");
long physicalFree = osmxb.getFreePhysicalMemorySize() / byteToMb;
long physicalTotal = osmxb.getTotalPhysicalMemorySize() / byteToMb;
long physicalUse = physicalTotal - physicalFree;
baseInfo += format("操作系统内存信息", "*");
baseInfo += format("");
baseInfo += format("操作系统的版本:" + os);
baseInfo += format("操作系统内存已使用:" + physicalFree + " MB");
baseInfo += format("操作系统内存剩余:" + physicalUse + " MB");
baseInfo += format("操作系统总内存:" + physicalTotal + " MB");
baseInfo += format("");
return baseInfo;
}
/**
* 记录虚拟机内存
* @param baseInfo
* @return
*/
private static String getJVMMemoryInfo(String baseInfo) {
// 虚拟机级内存情况查询
long vmFree = 0;
long vmUse = 0;
long vmTotal = 0;
long vmMax = 0;
int byteToMb = 1024 * 1024;
Runtime rt = Runtime.getRuntime();
vmTotal = rt.totalMemory() / byteToMb;
vmFree = rt.freeMemory() / byteToMb;
vmMax = rt.maxMemory() / byteToMb;
vmUse = vmTotal - vmFree;
baseInfo += format("JVM内存信息", "*");
baseInfo += format("");
baseInfo += format("JVM内存已用的空间为:" + vmUse + " MB");
baseInfo += format("" + "JVM内存的空闲空间为:" + vmFree + " MB");
baseInfo += format("" + "JVM总内总存空间为:" + vmTotal + " MB");
baseInfo += format("" + "JVM总内存最大空间为:" + vmMax + " MB");
baseInfo += format("");
return baseInfo;
}
/**
* 记录堆内存信息
* @param baseInfo
* @return
*/
private static String getHeapInfo(String baseInfo) {
int byteToMb = 1024 * 1024;
MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();
MemoryUsage usage = memorymbean.getHeapMemoryUsage();
baseInfo += format("堆内存信息", "*");
baseInfo += format("");
baseInfo += format("初始堆大小:" + usage.getInit() / byteToMb + "MB");
baseInfo += format("最大值:" + usage.getMax() / byteToMb + "MB");
baseInfo += format("已使用:" + usage.getUsed() / byteToMb + "MB");
baseInfo += format("");
return baseInfo;
}
/**
* 记录垃圾收集信息
* @param baseInfo
* @return
*/
private static String getGCInfo(String baseInfo) {
List<GarbageCollectorMXBean> gcmList = ManagementFactory.getGarbageCollectorMXBeans();
baseInfo += format("垃圾收集信息", "*");
baseInfo += format("");
for (GarbageCollectorMXBean gcm : gcmList) {
baseInfo += format("垃圾收集器名称:" + gcm.getName());
long collectionTime = gcm.getCollectionTime();
long collectionCount = gcm.getCollectionCount();
baseInfo += format("垃圾收集次数:" + collectionCount + " 次,垃圾收集时间:" + collectionTime + "毫秒");
}
baseInfo += format("");
return baseInfo;
}
/**
* 记录线程信息
* @param baseInfo
* @return
*/
private static String getThreadInfo(String baseInfo) {
ThreadMXBean tm = ManagementFactory.getThreadMXBean();
baseInfo += format("线程信息", "*");
baseInfo += format("");
baseInfo += format("线程数:" + tm.getThreadCount());
baseInfo += format("最大线程数:" + tm.getPeakThreadCount());
baseInfo += format("守护线程数:" + tm.getDaemonThreadCount());
baseInfo += format("");
return baseInfo;
}
private static String format(String value) {
return format(value, null);
}
private static String format(String value, String fill) {
Font font = new Font("Menlo", Font.PLAIN, 12);
AffineTransform affinetransform = new AffineTransform();
FontRenderContext frc = new FontRenderContext(affinetransform, true, true);
StringBuilder valueBuilder = new StringBuilder();
if (StringUtils.isBlank(fill)) {
fill = " ";
}
if (StringUtils.isNotBlank(value)) {
valueBuilder.append(" ").append(value).append(" ");
}
double fillWidth = font.getStringBounds(fill, frc).getWidth();
double contentWidth = font.getStringBounds(valueBuilder.toString(), frc).getWidth();
double left = 300 - contentWidth / 2.0;
while (left > 0) {
valueBuilder.insert(0, fill);
left -= fillWidth;
}
while (font.getStringBounds(valueBuilder.toString(), frc).getWidth() < 600) {
valueBuilder.append(fill);
}
valueBuilder.append("\n");
return valueBuilder.toString();
}
}
这样的话,我们可以做定时推送。每12小时发送一次或者根据自己的实际需要去看jvm相关的参数。这样就可以实现对系统的内部进行监测。