性能监控与调优(上篇)

上一篇

目录

概述前言

性能监控与调优(上篇)
性能监控:一种以非强行或者入侵方式收集或查看应用运营性能数据的活动。监控通常是指一种在生产、质量评估或者开发环境下实施的带有预防或主动性的活动。当应用相关干系人提出性能问题却没有提供足够多的线索时,首先我们需要进行性能监控,随后是性能分析。

性能分析是针对性能问题的答复结果,关注的范围通常比性能监控更加集中。一种以侵入方式收集运行性能数据的活动,它会影响应用的吞吐量或响应性。性能分析很少在生产环境下进行,通常是在质量评估、系统测试或者开发环境下进行,是性能监控之后的步骤。

性能调优一种为改善应用响应性或香吐量而更改参数、源代码、属性配置的活动,性能调优是在性能监控、性能分析之后的活动。

性能评价/测试指标

停顿时间(或晌应时间)

性能监控与调优(上篇)
设置最大暂停时间
-XX:MaxGCPauseMillis

JVM监控及诊断工具-命令行篇

概述

性能诊断是软件工程师在目常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益。
Java 作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关注。可能造成Java应用出现性能问题的囚素非常多,例如线程控制、磁盘读写、数据库访问、网络I/0、垃圾收集等。想要定位这些问题,一款优秀的性能诊断工具必不可少。
性能监控与调优(上篇)

jps:查看正在运行的Java进程

基本情况

jps(Java Process Status) :显示指定系统内所有的HotSpot虚拟机进程(查看虚拟机进程信.息),可用于查询正在运行的虚拟机进程
说明:对于本地虚拟机进程来说,进程的本地虚拟机ID与操作系统的进程ID是一致的,是唯一的。

基本语法:

jps [options] [host id]

options

性能监控与调优(上篇)

hostid

性能监控与调优(上篇)

jstat :查看心JVM统计信息

jstat(JVM statistics Monitoring Tool):用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。
在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。

基本语法

jstat -< option> [-t] [-h< lines>] < vmid> [< interval>[< count>]]
查看命令相关参数:
jstat -h或jstat -help

option参数

·类装载相关的:
-class:显示classLoader的相关信息:类的装载、卸载数量、总空间、
类装载所消耗的时间等
·垃圾回收相关的:
·-gc:显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、己用空间、Gc时间合计等信息。
性能监控与调优(上篇)

. -gccapacity:显示内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间。
. -gcutil:显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比。
-gccause:与-gcutil功能一样,但是会额外输出导致最后一次或当前正在发生的GC产生的原因。
-gcnew:显示新生代Gc状况
.-gcnewcapacity:显示内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间
.-geold:显示老年代Gc状况
JIT相关的:
. -compiler:显示JIT编译器编译过的方法、耗时等信息-printcompilation:输出已经被JIT编译的方法

interval参数

用于指定输出统计数据的周期,单位为毫秒。即:查询间隔

count参数

用于指定查询的总次数

-t参数

可以在输出信息前加上一个Timestamp列,显示程序的运行时间。单位:秒

-h参数

可以在周期性数据输出时,输出多少行数据后输出一个表头信息

补充

我们可以比较Java进程的启动时间以及总.GC 时间(GCT 列),或者两次测量的间隔时间以及总 GC时间的增量,来得出 GC时间占运行时间的比例。
如果该比例超过20%,则说明日前堆的压力较大;如果该比例超过 90%,则说明堆里几乎没有可用空间,随时都可能抛出OOM异常

jstat还可以用来判断是否出现内存泄漏
第1步:
在长时间运行的 Java 程序中,我们可以运行jstat命令连续获取多行性能数据,并取这几行数据中 OU 列(即已占用的老年代内存)的最小值。
第2步:
然后,我们每隔一段较长的时间重复一次上述操作,来获得多组 OU最小值。如果这些值呈上涨趋势,则说明该Java程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏

jinfo:实时查看和修改JVM配置参数

基本情况

jinfo(Configuration Thfo for Java)
查看虚拟机配置参数信息,也可用于调整虚拟机的配置参数。
在很多情况下,Java应用程序不会指定所有的Java虚拟机参数。而此时,开发人员可能不知道某一个具体的Java虚拟机参数的默认值。在这种情况下,可能需要通过查找文档获取某个参数的默认值。这个查找过程可能是非常艰难的。但有了jinfo工具,开发人员可以很方便地找到ava虚拟机参数的当前值。

基本语法

性能监控与调优(上篇)

查看

jinfo -sysprops PID 可以查看由System.getProperties();取得的参数
jinfo -flags PID查看曾经赋过值的一些参故
jinfo -flag 具体参数 PID 查看某个java进程的具体参数的值

修改

针对boolean类型 jinfo -flag [+|-]具体参数 PID
针对非boolean类型 jinfo -flag 具体参数=具体参数值 PID
性能监控与调优(上篇)

扩展

java -XX:+PrintFlagsInitial 查看所有JVM参数启动的初始值
java -XX:+PrintFlagsFinal 查看所有JVM参数的最终值
java -XX:+PrintCommandLineFlags 查看那些已经被用户或者JVM设置过的详细的XX参数的名称和值

jmap:导出内存映像文件&内存使用情况

基本情况

jmap(JVM Memory Map):作用一方面是获取dump文件(堆转储快照文件,二进制文件),它逐可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。
开发人员可以在控制台中输入命令“jmap -help”查阅jmap工具的具体使用方式和一些标准选项配置。

基本语法

性能监控与调优(上篇)
-dump
生成Java堆转储快照: dump文件。特别的:-dump:live只保存堆中的存活对象
-heap
输出整个堆空间的详细信息,包括GC的使用、堆配置信息,以及内存的使用信息等
-histo
输出堆中对象的统计信息,包括类、实例数量和合计容量。特别的: -histo:live只统计堆中的存活对象
-permstat
以ClassLoader为统计口径输出永久代的内存状态信息,仅linux/solaris平台有效
-finalizerinfo
显示在F-Queue中等待Finalizer线程执行finalize方法的对象,仅linux/solaris平台有效
-F
当虚拟机进程对-dump选项没有任何响应时,可使用此选项强制执行生成dump文件,仅linux/solaris平台有效
-h / -help
jmap工具使用的帮助命令
-J< flag>
传递参数给jmap启动的jvm

使用

使用1:导出内存映像文件

一般来说,使用jmap指令生成dump文件的操作算得上是最常用的jmap命令之一,将堆中所有存活对象导出至一个文件之中。
Heap Dump又叫做堆存储文件,指一个Java进程在某个时间点的内存快照。Heap Dump在触发内存快照的时候会保存此刻的信息如下:
. All 0bjects
class,fields ,primitive values and references
. All classes
classLoader ,name , super class,static fields
.Garbage collection Roots
objects defined to be reachable by the JVM
Thread stacks and Local Variables
The call-stacks of threads at the moment of the snapshot,and per-frame information about local objects
说明:
1.通常在写Heap Dump文件前会触发一次Full Gc,所以heap dump文件里保存的都是FullGC后留下的对象信息。
2.由于生成dump文件比较耗时,因此大家需要耐心等待,尤其是大内存镜像生成dump文件则需要耗费更长的时间来完成。
手动的方式
jmap -dump:format=b,file= <filename.hprof> < pid>
jmap -dump:live,format=b,file= <filename.hprof> < pid>

当程序发生OOM退出系统时,一些瞬时信息都随着程序的终止而消失,而重现oOM问题往往比较困难或者耗时。此时若能在OOM时,自动出dump文件就显得非常迫切。
这里介绍一种比较常用的取得堆快照文件的方法,即使用:
-XX:+HeapDumpOnOutOfMemoryError:在程序发生OOM时,导出应用程序的当前堆快照。
-XX :HeapDumpPath:可以指定堆快照的保存位置。
比如:
-Xmx100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\m.hprof
自动的方式
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=<filename.hprof>

使用2:显示堆内存相关信息

jmap -heap pid
-jmap -histo
由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。
举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么: live选项将无法探知到这些对象。
另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去。
与前面讲的jstat则不同,垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jsfat只需直接读取即可。

使用3:其它作用

jmap -permstat pid
查看系统的ClassLoader信息
jmap -finalizerinfo
查看堆积在finalizer队列中的对象

jhat : JDK自带堆分析工具

基本情况

Sun JDK提供的jhat命令与jmap命令搭配使用,用于分析jmap生成的heap dump文件(堆转储快照)。jhat内置了一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,用户可以在浏览器中查看分析结果(分析虚拟机转储快照信息)。
使用了jhat命令,就启动了一个http服务,端口是7000,即http: / / localhost:7000/,就可以在浏览器里分析。
说明:jhat命令在JDK9、JDK10中已经被删除,官方建议用visualVM代替。
性能监控与调优(上篇)

jstack:打印VM中线程快照

基本情况

jstack(JVM Stack Trace):用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)。线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。
生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用jstack显示各个线程调用的堆栈情况。
在thread dump中,要留意下面几种状态│
·死锁,Deadlock(重点关注)
·等待资源,Waiting on condition(重点关注)
.等待获取监视器,waiting on monitor entry(重点关注)·阻塞,Blocked(重点关注>
·执行中,Runnable
·暂停,Suspended

基本语法

性能监控与调优(上篇)
性能监控与调优(上篇)

jcmd:多功能命令行

基本情况

在DK 1.7以后,新增了一个命令行工具jcmd。
它是一个多功能的工具,可以用来实现前面除了jstat之外所有命令的功能。比如:用它来导出堆、内存使用、查看Java进程、导出线程信息、执行GC、JVM运行时间等。
jcmd拥有jmap的大部分功能,并且在Oracle的官方网站上也推荐使用jcmd命令代jmap命令

具体语法

jcmd -l 列出所有的JVM进程
jcmd pid helpo 针对指定的进程,列出支持的所有命令
jcmd pid 具体命令团 显示指定进程的指令命令的数据

jstatd:远程主机信息收集

性能监控与调优(上篇)

JVM监控及诊断工具-GUl篇

工具概述

性能监控与调优(上篇)
性能监控与调优(上篇)

jconsole

·从]ava5开始,在JDK中自带的java监控和管理控制台。
·用于对JVA中内存、线程和类等的监控,是一个基于7NX(java management extensions)的GUT性能监控工具。在安装jdk目录中的bin中

visual VM

基本概述

. Visual VM是一个功能强大的多合一故障诊断和性能监控的可视化工具。
·它集成了多个JDK命令行工具,使用visual VM可用于显示虚拟机进程及进程的配置和环境信息(jps,jinfo),监视应用程序的CPU、Gc、堆、方法区及线程的信息(jstat、jstack)等,甚至代替JConsole.
在DK 6 Update 7以后,Visual vn便作为DK的一部分发布 (VisualM在JDK/bin目录下)

连接方式

性能监控与调优(上篇)

功能

性能监控与调优(上篇)

eclipse MAT

基本概述

MAT(Memory Analyzer Tool)工具是一款功能强大的Java堆内存分析器。可以用于查找内存泄漏以及查看内存消耗情况。
MAT是基于Eclipse开发的,不仅可以单独使用,还可以作为插件的形式嵌入在Eclipse中使用。是一款免费的性能分析工具,使用起来非常方便。

获取堆dump文件

dump文件内容

MAT可以分析heap dump文件。在进行内存分析时,只要获得了反映当前设备内存映像的hprof文件,通过MAT打开就可以直观地看到当前的内存信息。
一般说来,这些内存信息包含:
·所有的对象信息,包括对象实例、成员变量、存储于栈中的基本类型值和存储于堆中的其他对象的引用值。
·所有的类信息,包括classloader、类名称、父类、静态变量等. GCRoot到所有的这些对象的引用路径
·线程信息,包括线程的调用栈及此线程的线程局部变量(TLS)

获取dump文件方式

性能监控与调优(上篇)

分析堆dump文件

性能监控与调优(上篇)

histogram

MAT 的直方图和jmap的-histo子命令一样,都能够展示各个类的实例数目以及这些实例的 Shallowheap总和。但是,MAT 的直方图还能够计算Retained heap,并支持基于实例数目或 Retainedheap 的排序方式(默认为Shallow heap) .
此外,MAT还可以将直方图中的类按照超类、类加载器或者包名分组。
当选中某个类时,MAT界面左上角的 Inspector窗口将展示该类的 Class 实例的相关信息,如类加载器等。

浅堆与深堆

性能监控与调优(上篇)
保留集(Retained Set):
对象A的保留集指当对象A被垃圾回收后,可以被释放的所有的对象集合(包括对象A本身),即对象A的保留集可以被认为是只能通过对象A被直接或间接访问到的所有对象的集合。通俗地说,就是指仅被对象A所持有的对象的集合
深堆(Retained Heap):
深堆是指对象的保留集中所有的对象的浅堆大小之和
注意:浅堆指对象本身占用的内存,不包括其内部引用对象的大小。一个对象的深堆指只能通过该对象访问到的(直接或间接)所有对象的浅堆之和,即对象被回收后,可以释放的真实空间。

补充:对象实际大小

另外一个常用的概念是对象的实际大小。这里,对象的实际大小定义为一个对象所能触及的所有对象的浅堆大小之和,也就是通常意义上我们说的对象大小。与深堆相比,似乎这个在日常开发中更为直观和被人接受,但实际上,这个概念和垃圾回收无关。
性能监控与调优(上篇)

支配树

MAT提供了一个称为支配树(Dominator Tree〉的对象图。支配树体现了对象实例间的支配关系。在对象引用图中,所有指向对象B的路径都经过对象A,则认为对象A支配对象B。如果对象A是离对象B最近的一个支配对象,则认为对象A为对象B的直接支配者。支配树是基于对象间的引用图所建立的,
它有以下基本性质:
1.对象A的子树(所有被对象A支配的对象集合)表示对象A的保留集(retained set),即深堆。
2.如果对象A支配对象B,那么对象A的直接支配者也支配对象B。
3.支配树的边与对象引用图的边不直接对应。

如下图所示:左图表示对象引用图,右图表示左图所对应的支配树。对象A和B由根对象直接支配,由于在到对象c的路径中,可以经过A,也可以经过B,因此对象c的直接支配者也是根对象。对象F与对象D相互引用,因为到对象F的所有路径必然经过对象D,因此,对象D是对象F的直接支配者。而到对象D的所有路径中,必然经过对象c,即使是从对象F到对象D的引用,从根节点出发,也是经过对象C的,所以,对象D的直接支配者为对象C。
性能监控与调优(上篇)

上一篇:JAVA内存泄露查询


下一篇:html5 file 上传文件