tags: java, troubleshooting, monitorhtml
一句话归纳:java应用监测,为何?监测什么?如何监测?本文为你解答。java
java开发人员都知道,启动java应用使用的是java
(class
文件)或java -jar
(jar
或war
包)命令。而java
命令其实就是启动一个java虚拟机(JVM
),程序就是运行在JVM
上,JVM
负责类加载,运行时区域堆栈分配等工做,而堆栈分别用于程序中的对象及线程使用,分别影响的系统的cpu及内存,若是程序涉及文件或数据读写,还会影响系统的IO。所以,一个java应用启动后,若是不对它所占用的资源状况进行监测,无疑于一架飞机起飞了,却没有仪表盘,这种飞机估计没有人敢坐。所以,做为开发人员,得清楚应用启动后的运行状况,并可以对应用运行情况进行监测,如此,才能及时预测有可能发生的问题进行及时修正或发生问题后能够更快,更好地找到缘由所在,进而解决。可喜的是,程序自己,java工具和第三方工具,都为咱们提供了不少监测java应用的方法,所以,做为java开发人员,有必要对它们作一个系统的了解,以便于在实际应用中(特别是在生产环境中)更从容,更有效率的处理问题。linux
一个java应用运行起来,若出现问题,咱们第一反应确定是查看日志,查看一下具体是报什么错,若没有报错,只是运行很慢,或者只是暂时尚未报错,那咱们须要监测什么内容呢?这一节,对比咱们平时使用操做系统,来看看对于java应用,须要监测什么内容。ios
对于咱们平时使用的操做系统,如windows
,linux
系统,出现应用打开缓慢,系统响应缓慢,通常就是先查看系统的cpu运行和内存使用状况,找出占用资源高的进程,定位缘由,在windows
,直接在任务管理器-->性能
中查看,以下图。windows
在linux
,可使用top
,free
,df
,iostat
等命令进行查看,以下图。数组
在平常的运维过程当中,也是对系统的磁盘使用、IO、CPU、内存、网络等状况进行监测,争取及时发现占用资源高的进程,定位问题而后处理。tomcat
相对于操做系统,java应用须要监测的内容也有相似的地方,如占用的cpu状况,内存状况,其中,会包含java应用的JVM参数,堆占用状况,线程运行状态,类加载状况,垃圾回收(GC
)状况。至于为何须要监测这些内容,就须要对java的虚拟机(JVM)有必定的了解,因为本文JVM涉及内容较多,后面有机会再对JVM进行详细讲解,这里能够对java的JVM体系做一个简要介绍,以便于读者对后面章节的理解。见下图:安全
当java运行一个应用,就会生成一个JVM的实例,而java应用则运行于此JVM实例中,当应用退出,JVM实例也会关闭。启动多个java应用,也会启动多个JVM实例,它们不会相互影响(固然,它们都会占用系统的资源)。网络
虚拟机主要有三大模块,一个类加载子系统(Class Loader Subsystem
,负责加载类),一个执行引擎(Execution Engine
,负责执行类的方法指令和垃圾回收),一个运行时数据区(Runtime Data Areas
,负责存放程序运行时的数据)。oracle
其中运行时数据区分为方法区(存储如类信息,方法信息,引用,常量池等),堆(存储类实例对象和数组),java栈(以栈方式存放以帧为单位保存线程的运行状态帧),本地方法栈(跟本地方法相关的数据区),程序计数器(每个线程都有它本身的程序计数器,表示下一条将被执行指令的“地址”)。
java应用启动流程就是经过类加载子系统加载相关的类,而后把相关数据如类信息,方法等存到方法区的栈中,实例化相关的类,同时把实例对象存储在堆中,程序运行位置则是每一个线程使用计数器来指定。方法区和堆是线程共享的,程序计数器及Java栈是线程私有的。
运行时数据区是java应用运行时的监测区域,其中各个区域的内存状况,特别是堆的内存使用状况,是重点区域。堆还会分年轻代、年老代及 Metaspace
,垃圾回收器会进行分代回收。经过它的回收状况监测,能够检测到是否存在内存泄漏,而java栈则与线程有关,线程的运行状态又与CPU相关,所以java栈的监测能够知道CPU占用过大的问题,同时方法区和java栈的占用内存大小也是一个监测的指标。
通过上面的描述,咱们大概已经知道一个java应用启动后,咱们为何须要监测java应用以及须要监测哪些东西。那落实到实际应用中,该如何进行监测呢?下面经过对java应用监测工具及方法进行一个概要介绍,后续将会以系列文章的形式,对各个监测工具及方法进行详细介绍。
按监测工具的监测方式,主要分为如下四大类:
程序内置监测就比较简单,在初学java时,最经常使用的就是使用System.out.println()
把本身想要输出的内容输出,在开发阶段也有人喜欢这样,一方面能够输出业务内容,监测功能的正常与否,另外一方面能够输出系统属性System.getProperties()
及System.getProperty()
。固然,如今更多的使用日志框架进行输出,并把日志按级别输出到文件中,如log4j
及logback
。对于Spring Boot
应用,还可使用actuator
来监测程序运行状况。tomcat
容器自身也带有监测页面。此类监测主要特色是程序内置,而且经过日志输出来监测,开发人员相对比较熟悉了,通常来讲在开发和测试阶段比较经常使用,而生产环境下,日志通常是error
级别或者因为安全考虑,自带的一些监测页面有可能会关闭。所以,此类监测再也不细说。
在jdk的安装目录下的的bin目录,已经提供了多种命令行监测工具,以便于开发人员和运维人员监测java应用,同时方便开发及运维人员对问题进行诊断,所以,此类工具是java应用监测的重要手段。通常来讲,经常使用的命令行工具包括jps
,jinfo
,jmap
,jstack
,jstat
,其中
jps
查看java进程IDjinfo
查看及调整虚拟机参数jmap
查看堆(heap)使用状况及生成堆快照jstack
查看线程运行状态及生成线程快照jstat
显示进程中的类装载、内存、垃圾收集等运行数据。经过这些工具,基本上能够了解java应用的内存变化状态,线程运行状态等信息,进而为应用监测及问题诊断提供依据。后面的文章将会对这些工具进行详细描述。
除了命令行工具,在windows平台下,jdk还提供了可视化监测工具,以更直观,更方便的方式对java应用运行情况进行监测。这两款工具分别是jconsole
和jvisualvm
,在jdk下的bin目录下能够找到。它们都可监测本地及远程的java应用,包括堆使用状况,线程使用,cpu使用,类加载状况,gc状况,jvisualvm
还能够生成相应的堆和线程快照,同时还可使用相应的插件,以便于进一步分析。后面的文章将会对这两款工具的使用进行详细描述。
除了java自带的工具,一些第三方的工具也是监测及分析诊断,性能调优的利器,包括MAT
,BTrace
及Arthas
。其中
MAT
是eclipse
的内存分析插件,经过MAT
能够对dump出来的堆快照进行分析,而且辅助分析内存泄露缘由,快速的计算出在内存中对象的占用大小,垃圾收集器的回收工做状况,并能够经过报表直观的查看到可能形成这种结果的对象。BTrace
是是sun推出的一款Java 动态、安全追踪(监控)工具,能够在不停机的状况下监控系统运行状况,而且作到最少的侵入,占用最少的系统资源。特别适用在生产环境下对java应用进行监测,问题排查。Arthas
是阿里开源的在线Java诊断工具,一样能够在不停机状况监控系统,包括内存状况,线程状况,GC状况,运行时数据,也能够监测方法参数、返回值,异常返回等数据,堪称神器,在生产环境下使用很是方便。后面的文章将会对这三款第三方工具的使用进行详细描述。
但愿经过本系列的文章,让你们能够对java的应用监测技术有所了解,熟悉各类监测工具,以便于在遇到线上问题(特别是性能问题,oom问题等),能够从容面对及处理。
https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/
https://www.cnblogs.com/java-my-life/archive/2012/08/01/2615221.html