JVM监控方法 - JvmMonitor

标签: jvm 方法 jvmmonitor | 发表时间:2017-01-05 15: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 方法 jvmmonitor] 推荐:

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).

JVM学习之:浅谈方法调用

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

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 内核中断内幕.

深入理解JVM

- 小伟 - ITeye论坛最新讨论
1   Java技术与Java虚拟机. 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API). 图1   Java四个方面的关系. 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件).

jvm垃圾回收

- Cano - 淘宝共享数据平台 tbdata.org
在jvm中堆空间划分为三个代:年轻代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation). 年轻代和年老代是存储动态产生的对象. 永久带主要是存储的是java的类信息,包括解析得到的方法、属性、字段等等. 我们这里讨论的垃圾回收主要是针对年轻代和年老代.

Azul开源Zing Jvm

- - InfoQ cn
4月末,继Zing 5.2 之后,. Azul Systems宣布他们将无停顿(pauseless )的 Zing JVM提供给开源软件开发者和项目,以供开发和测试. Azul Systems 工程部副总裁和合作创始人Shyam Pillalamarri向InfoQ说明道:. 我们的部署很大一部分基于开源组件,所以我们认为:“假设我们不能将一些有价值的东西免费提供给开源项目贡献者,他们将一直受限于从Java虚拟机(JVM)视角所看到的内容”,他们将不会考虑额外的用例,或者选择其他能解决了所有内存或扩展性问题、类似Zing的系统.

JVM参数设置

- - 企业架构 - ITeye博客
-Xms768m -Xmx1280m  jvm堆的最小值和最大值设置,一般设成相同值,避免频繁分配堆空间. -XX:NewSize=128m -XX:MaxNewSize=128m  年轻代最小值和最大值设置(年轻代设定了,年老代也就定了),也可以用参数-XX:NewRatio=4,年老代和年轻代的大小比,这里128m有点小了,官方建议的是heap的3/8,差不多280m.