JVM监控方法 - JvmMonitor
在日常项目运作中,有时我们需要将JVM的信息以我们期望的方式输出到日志中,然后对日志对日志进行实时监控。
1.JVM监控日志
#jvm-monitor-digest.log#
说明:记录了jvm中的一些堆内存和线程信息以及堆外内存,例
2014-07-10 00:00:06,599 INFO JVM INFO - (1325.5,5390)(7.4,135,614,3601)(5.46,5390) 2014-07-10 00:00:36,599 INFO JVM INFO - (1745.07,5390)(7.4,135,614,3601)(5.46,5390)
格式:(used_heap,max_heap)(current_thread_cpu_time,daemon_thread_count,total_thread_count,total_started_thread_count)(non_heap_reserved_memory,non_heap_max_memory)
2.实现原理
创建一个守护线程定时(每隔30s)统计堆内存,线程信息,堆外内存,并输出。
堆内存信息:
直接使用java内存管理Bean MemoryMXBean获取堆内存信息。
MemoryMXBean获取方法:
private static final MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
线程信息:
直接使用java线程管理Bean ThreadMXBean获取堆内存信息。
MemoryMXBean获取方法:
private static final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
格式:(used_heap,max_heap)(current_thread_cpu_time,daemon_thread_count,total_thread_count,total_started_thread_count)(non_heap_reserved_memory,non_heap_max_memory)
堆外内存:
这里是指狭义的堆外内存,是指java.nio.DirectByteBuffer在创建的时候分配的内存,也叫Direct memory。堆外内存信息可以通过反射获取java.nio.Bits对应的字段maxMemory和reservedMemory,注意这两个字段的单位是bytes。
http://www.open-open.com/lib/view/open1431570358826.html
代码
public class JvmMonitor { protected static final Log logger = LogFactory.getLog("jvm-monitor-digest"); private static final String SPLITTER = ","; private static final DecimalFormat decimalformat = new DecimalFormat("#.##"); private static final MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); private static final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); private static Field maxDirectedMemoryField; private static Field reservedDirectedMemoryField; public JvmMonitor() throws Exception { Class clz = Class.forName("java.nio.Bits"); maxDirectedMemoryField = clz.getDeclaredField("maxMemory"); maxDirectedMemoryField.setAccessible(true); reservedDirectedMemoryField = clz.getDeclaredField("reservedMemory"); reservedDirectedMemoryField.setAccessible(true); } public void start() { Thread monitor = new Thread() { public void run() { try { while (true) { JvmMonitor.logger.info(JvmMonitor.this.getJVMInfo()); sleep(30000L); } } catch (Exception e) { e.printStackTrace(); } } }; monitor.setDaemon(true); monitor.setName("JVM INFO"); monitor.start(); } private String getJVMInfo() { MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage(); StringBuilder sb = new StringBuilder(); sb.append("("); sb.append(formatValue(memoryUsage.getUsed())).append(","); sb.append(formatValue(memoryUsage.getMax())); sb.append(")"); sb.append("("); sb.append(formatNanosecond(threadMXBean.getCurrentThreadCpuTime())).append(","); sb.append(threadMXBean.getDaemonThreadCount()).append(","); sb.append(threadMXBean.getThreadCount()).append(","); sb.append(threadMXBean.getTotalStartedThreadCount()); sb.append(")"); sb.append(getDirectedMemoryInfo()); return sb.toString(); } private String getDirectedMemoryInfo() { StringBuilder sb = new StringBuilder(); Long maxMemoryValue = Long.valueOf(0L); Long reservedMemoryValue = Long.valueOf(0L); try { maxMemoryValue = (Long)maxDirectedMemoryField.get(null); reservedMemoryValue = (Long)reservedDirectedMemoryField.get(null); } catch (Exception e) { } sb.append("("); sb.append(formatValue(reservedMemoryValue.longValue())); sb.append(","); sb.append(formatValue(maxMemoryValue.longValue())); sb.append(")"); return sb.toString(); } private static String formatValue(long value) { Double tempValue = Double.valueOf(new Double(value).doubleValue() / 1024.0D / 1024.0D); return decimalformat.format(tempValue); } private String formatNanosecond(long value) { Double tempValue = Double.valueOf(new Double(value).doubleValue() / 1000000000.0D); return decimalformat.format(tempValue); } }
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐