`
Josh_Persistence
  • 浏览: 1632189 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类

JVM监控方法 - JvmMonitor

    博客分类:
  • Java
阅读更多

        在日常项目运作中,有时我们需要将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);
  }
}

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics