JVM监控方法 - JvmMonitor

标签: jvm 监控 方法 | 发表时间:2017-01-05 23:18 | 作者:Josh_Persistence
出处:http://www.iteye.com

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



相关 [jvm 监控 方法] 推荐:

JVM监控方法 - JvmMonitor

- - 编程语言 - ITeye博客
        在日常项目运作中,有时我们需要将JVM的信息以我们期望的方式输出到日志中,然后对日志对日志进行实时监控. 说明:记录了jvm中的一些堆内存和线程信息以及堆外内存,例. 格式:(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 VisualVM监控远程JVM

- - 互联网 - ITeye博客
我们经常需要对我们的开发的软件做各种测试, 软件对系统资源的使用情况更是不可少, 目前有多个监控工具, 相比JProfiler对系统资源尤其是内存的消耗是非常庞大,JDK1.6开始自带的VisualVM就是不错的监控工具. 这个工具就在JAVA_HOME\bin\目录下的jvisualvm.exe, 双击这个文件就能看到一个比较直观的界面.

使用Java VisualVM监控远程JVM

- - Java - 编程语言 - ITeye博客
我们经常需要对我们的开发的软件做各种测试, 软件对系统资源的使用情况更是不可少, 目前有多个监控工具, 相比JProfiler对系统资源尤其是内存的消耗是非常庞大,JDK1.6开始自带的VisualVM就是不错的监控工具. 这个工具就在JAVA_HOME\bin\目录下的jvisualvm.exe, 双击这个文件就能看到一个比较直观的界面.

JVM学习之:浅谈方法调用

- - CSDN博客推荐文章
前面提到了几种方法的调用,虚拟机也提供了对应的字节码指令,分别是:. invokestatic:调用静态方法. invokespecial:调用构造器方法,私有方法以及父类方法. invokevirtual:调用虚方法以及final方法(虽然用invokevirtual调用,可是因为final方法的不可覆盖性,因此也是非虚方法).

JVM性能调优监控工具专题二:VisualVM基本篇之监控JVM内存,CPU,线程

- - ITeye博客
        上一个专题中讲述了JVM中自带的各种性能测试的小工具:包括jps,jstatck,jmap,jhat,jsats,hprof.         这样会造成不必要的麻烦,难道就没有一个tool可以 包括如上所有的功能. 答案是有的,自从 JDK 6 Update 7以后,提供了一全新的性能检测工具:VisualVM,VisualVM对运行中的Java应用提供了可视化的信息展示, 它是很多工具的整合包,整合了JConsole,jstat,jinfo,jstack以及jmap.

JVM性能调优监控工具专题三:VisualVM基本篇之快照分析、监控GC、Eclipse集成

- - 行业应用 - ITeye博客
上一个专题专门举例说明了使用VisualVM进行远程监控以及对Tomcat的远程监控,如果有兴趣,可以查看:. 该专题将讲解如何使用VisualVM生成快照、以及如何对JVM的GC进行监控,最后举例说明如何将VisualVM和eclipse进行集成. 我们可以使用 VisualVM 的快照功能生成任意个性能分析快照并保存到本地来辅助我们进行性能分析.

JVM 调优 —— GC 长时间停顿问题及解决方法

- - ImportNew
垃圾收集器长时间停顿,表现在 Web 页面上可能是页面响应码 500 之类的服务器错误问题,如果是个支付过程可能会导致支付失败,将造成公司的直接经济损失,程序员要尽量避免或者说减少此类情况发生. 并发模式失败(concurrent mode failure). 在 CMS 启动过程中,新生代提升速度过快,老年代收集速度赶不上新生代提升速度.

JVM研究

- - 开源软件 - ITeye博客
每天接客户的电话都是战战兢兢的,生怕再出什么幺蛾子了. 我想Java做的久一点的都有这样的经历,那这些问题的最终根结是在哪呢. JVM全称是Java Virtual Machine,Java虚拟机,也就是在计算机上再虚拟一个计算机,这和我们使用 VMWare不一样,那个虚拟的东西你是可以看到的,这个JVM你是看不到的,它存在内存中.

jvm调优

- - 互联网 - ITeye博客
printf "%x\n" 21742  找到耗时最长的进程. jstack pid | grep 54ee  定位某个类的方法. jstack 10535|grep -A 10 2a1d (最后十行). jmap 查询pid 内存线程. 附:TOP命令中需要关注的值:. (1)load average:此值反映了任务队列的平均长度;如果此值超过了CPU数量,则表示当前CPU数量不足以处理任务,负载过高.

学习JVM的References

- LightingMan - 淘宝JAVA中间件团队博客
本blog中列举了我学习JVM的references,会不断的更新,为了避免版权问题,就不在blog上提供references的下载了,感兴趣的同学可自行下载或购买,:). |— [ Hotspot GC论文 ]. |— [ 其他JVM GC ]. |— Linux内核源代码情景分析. |— Linux 内核中断内幕.