jvm监控
来源:互联网 发布:百度数据新闻网 编辑:程序博客网 时间:2024/05/19 23:24
学习java或者说使用java的人肯定对jvm不会陌生,根据最近工作需要,去网上专门学习了一下jvm监控相关的知识,看了很多的网页,此文中引用了很多,所以有些忘了记网址了,如果有作者看到了,有侵权的话,请告知删除。
好了,废话不多说,直接贴知识点。
Linux系统下的Jvm监控
一、Jps(JVM Process Status Tools)
语法:Jps [option] [hostid]
其中hostid默认为本机,而option选项包含以下选项
Option
Function
-q
只输出LVMID
-m
输出JVM启动时传给主类的方法
-l
输出主类的全名,如果是Jar则输出jar的路径
-v
输出JVM的启动参数
二、jstat(JVM Statistics Monitoring Tools)
Jstat主要用于监控虚拟机的各种运行状态信息,如类的装载、内存、垃圾回收、JIT编译器等,在没有GUI的服务器上,这款工具是首选的一款监控工具。
语法:jstat [option vmid [interval [s|ms] [vount] ] ]
参数interval和count分别表示查询间隔和查询次数,如每1毫秒查询一次进程20445的垃圾回收情况,监控20次,命令如下所示:
jstat –gc 20445 1 20
选项option代表用户需要查询的虚拟机的信息,主要分为3类:类装载、垃圾
回收和运行期的编译情况,具体如下表所示:
Option
Function
-class
监视类的装载、卸载数量以及类的装载总空间和耗费时间等
-gc
监视Java堆,包含eden、2个survivor区、old区和永久带区域的容量、已用空间、GC时间合计等信息
-gccapcity
监视内容与-gc相同,但输出主要关注Java区域用到的最大和最小空间
-gcutil
监视内容与-gc相同,但输出主要关注已使用空间占总空间的百分比
-gccause
与-gcutil输出信息相同,额外输出导致上次GC产生的原因
-gcnew
监控新生代的GC情况
-gcnewcapacity
与-gcnew监控信息相同,输出主要关注使用到的最大和最小空间
-gcold
监控老生代的GC情况
-gcoldcapacity
与-gcold监控信息相同,输出主要关注使用到的最大和最小空间
-gcpermcapacity
输出永久带用到的最大和最小空间
-compiler
输出JIT编译器编译过的方法、耗时信息
-printcompilation
输出已经被JIT编译的方法
jstat –class 20445 1 20
各项数据解释
Loaded:加载的类的个数。
Bytes:多字节加载。
Unloaded:卸载的类数。
Bytes:多字节的卸载。
Time:执行类加载和卸载操作的时间。
jstat –compiler 20445 1 20
各项数据解释
Compiled:执行的编译任务数。
Failed:失败的编译任务数。
Invalid:已失效的编译任务的数目。
Time:完成编译任务所花费的时间。
FailedType:上次失败编译的编译类型。
FailedMethod:上次失败编译的类名和方法。
jstat –gc 20445 100 10
各项数据解释
S0C:当前Survivor 空间0容量(KB)。
S1C:当前Survivor 空间1容量(KB)。
S0U:Survivor 空间0利用率(KB)。
S1U:Survivor 空间1利用率(KB)。
EC:当前Eden空间容量(KB)。
EU:Eden空间利用率(KB)。
OC:当前Old空间容量(KB)。
OU:Old空间利用率(KB)。
PC:当前Permanent空间容量(KB)。
PU:Permanent空间利用率(KB)。
YGC:Young 年轻一代GC事件数。
YGCT:Young 新生代垃圾收集时间。
FGC:全部GC事件的数目。
FGCT:完全垃圾收集时间。
GCT:垃圾收集总时间。
jstat –gccapacity 2540 100 5
各项数据解释
NGCMN:新生代最小容量(KB)。
NGCMX:新生代最大容量(KB)。
NGC:当前新生代容量(KB)。
S0C:当前Survivor 空间0容量(KB)。
S1C:当前Survivor 空间1容量(KB)。
EC:当前Eden空间容量(KB)。
OGCMN:Old老一代最小容量(KB)
OGCMX:Old老一代最大容量(KB)
OGC:当前Old老一代容量(KB)
OC:当前Old空间容量(KB)。
PGCMN:最小永久代容量
PGCMX:最大永久代容量
PGC:当前永久代容量
PC:当前永久代空间容量
YGC:年轻代GC事件数
FGC:全部GC事件数
jstat -gccause 2540 100 5
LGCC:上次GC发生的原因。
GCC:当前GC发生的原因。
Jstat -gcnew [线程id] [监控间隔时间] [监控打印次数]
S0C:
S1C:
S0U:
S1U:
TT:期限阈值。
MTT:最大期限阈值。
DSS:期望Survivor大小(KB)。
EC:当前Eden空间容量(KB)。
EU:Eden空间利用率(KB)。
YGC:Young 年轻一代GC事件数。
YGCT:Young 新生代垃圾收集时间。
Jstat -gcnewcapacity [线程id] [监控间隔时间] [监控打印次数]
NGCMN:
NGCMX:
NGC:
S0CMX:最大Survivor 0 空间容量
S0C:当前Survivor 0 空间容量
S1CMX:
S1C:
ECMX:最大Eden 空间容量
EC:
YGC:
FGC:
jstat -gcutil 2540 100 5
S0:Survivor 0 对于当前空间总容量的利用率百分比。
S1:Survivor 1对于当前空间总容量的利用率百分比。
E:Eden区的空间利用率百分比。
O:Old区的空间利用率百分比。
P:Permanent区的空间利用率百分比。
YGC:
YGCT:
FGC:
FGCT:
GCT:
三、jinfo(JVM configuration Info for Java)
Jinfo的作用是实时查看虚拟机的各项参数信息jps –v可以查看虚拟机在启动时被显式指定的参数信息,但是如果你想知道默认的一些参数信息呢?除了去查询对应的资料以外,jinfo就显得很重要了。
语法:jinfo [option] pid
Options
Function
no option
打印命令行标志和系统属性名称、值对。
-flag name
打印给定命令行标志的名称和值。
-flag [+|-]name
启用或禁用给定的布尔命令行标志。
-flag name=value
将给定的命令行标志设置为指定的值。
-flags
打印传递给JVM的命令行标志。对.
-sysprops
打印java系统属性名称值对。
-h
打印帮助信息
-help
打印帮助信息
四、jmap(JVM Memory Map for Java)
Jmap用于生成堆快照(heapdump)。当然我们有很多方法可以取到对应的dump信息,如我们通过JVM启动时加入启动参数 –XX:HeapDumpOnOutOfMemoryError参数,可以让JVM在出现内存溢出错误的时候自动生成dump文件,亦可以通过-XX:HeapDumpOnCtrlBreak参数,在运行时使用ctrl+break按键生成dump文件,当然我们也可以使用kill -3 pid的方式去恐吓JVM生成dump文件。Jmap的作用0久带的详细信息,如空间使用率、垃圾回收器等。其运行格式如下:
Jmap [option] vmip
Option的信息如下表所示
Option
Function
-dump
生成对应的dump信息,用法为-dump:[live,]format=b,file={fileName}
-finalizerinfo
显示在F-Queue中等待的Finalizer方法的对象(只在linux下生效)
-heap
显示堆的详细信息、垃圾回收器信息、参数配置、分代详情等
-histo
显示堆栈中的对象的统计信息,包含类、实例数量和合计容量
-permstat
以ClassLoder为统计口径显示永久带的内存状态
-F
当虚拟机对-dump无响应时可使用这个选项强制生成dump快照
示例:jmap -dump:format=b,file=yhj.dump 20445
(
①Jvm启动参数:
启动参数松散的聚合成三类:
行为参数(Behavioral Options):用于改变jvm的一些基础行为;
性能调优(Performance Tuning):用于jvm的性能调优;
调试参数(Debugging Options):一般用于打开跟踪、打印、输出等jvm参数,用于显示jvm更加详细的信息;
行为参数:
参数及其默认值
描述
-XX:-DisableExplicitGC
禁止调用System.gc();但jvm的gc仍然有效
-XX:+MaxFDLimit
最大化文件描述符的数量限制
-XX:+ScavengeBeforeFullGC
新生代GC优先于Full GC执行
-XX:+UseGCOverheadLimit
在抛出OOM之前限制jvm耗费在GC上的时间比例
-XX:-UseConcMarkSweepGC
对老生代采用并发标记交换算法进行GC
-XX:-UseParallelGC
启用并行GC
-XX:-UseParallelOldGC
对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用
-XX:-UseSerialGC
启用串行GC
-XX:+UseThreadPriorities
启用本地线程优先级
上面表格中黑体的三个参数代表着jvm中GC执行的三种方式,即串行、并行、并发;
串行(SerialGC)是jvm的默认GC方式,一般适用于小型应用和单处理器,算法比较简单,GC效率也较高,但可能会给应用带来停顿;
并行(ParallelGC)是指GC运行时,对应用程序运行没有影响,GC和app两者的线程在并发执行,这样可以最大限度不影响app的运行;
并发(ConcMarkSweepGC)是指多个线程并发执行GC,一般适用于多处理器系统中,可以提高GC的效率,但算法复杂,系统消耗较大;
性能调优:
参数及其默认值
描述
-XX:LargePageSizeInBytes=4m
设置用于Java堆的大页面尺寸
-XX:MaxHeapFreeRatio=70
GC后java堆中空闲量占的最大比例
-XX:MaxNewSize=size
新生成对象能占用内存的最大值
-XX:MaxPermSize=64m
老生代对象能占用内存的最大值
-XX:MinHeapFreeRatio=40
GC后java堆中空闲量占的最小比例
-XX:NewRatio=2
新生代内存容量与老生代内存容量的比例
-XX:NewSize=2.125m
新生代对象生成时占用内存的默认值
-XX:ReservedCodeCacheSize=32m
保留代码占用的内存容量
-XX:ThreadStackSize=512
设置线程栈大小,若为0则使用系统默认值
-XX:+UseLargePages
使用大页面内存
我们在日常性能调优中基本上都会用到以上黑体的这几个属性;
调试参数:
参数及其默认值
描述
-XX:-CITime
打印消耗在JIT编译的时间
-XX:ErrorFile=./hs_err_pid<pid>.log
保存错误日志或者数据到文件中
-XX:-ExtendedDTraceProbes
开启solaris特有的dtrace探针
-XX:HeapDumpPath=./java_pid<pid>.hprof
指定导出堆信息时的路径或文件名
-XX:-HeapDumpOnOutOfMemoryError
当首次遭遇OOM时导出此时堆中相关信息
-XX:OnError="<cmd args>;<cmd args>"
出现致命ERROR之后运行自定义命令
-XX:OnOutOfMemoryError="<cmd args>;<cmd args>"
当首次遭遇OOM时执行自定义命令
-XX:-PrintClassHistogram
遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同
-XX:-PrintConcurrentLocks
遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同
-XX:-PrintCommandLineFlags
打印在命令行中出现过的标记
-XX:-PrintCompilation
当一个方法被编译时打印相关信息
-XX:-PrintGC
每次GC时打印相关信息
-XX:-PrintGC Details
每次GC时打印详细信息
-XX:-PrintGCTimeStamps
打印每次GC的时间戳
-XX:-TraceClassLoading
跟踪类的加载信息
-XX:-TraceClassLoadingPreorder
跟踪被引用到的所有类的加载信息
-XX:-TraceClassResolution
跟踪常量池
-XX:-TraceClassUnloading
跟踪类的卸载信息
-XX:-TraceLoaderConstraints
跟踪类加载器约束的相关信息
当系统出现问题的时候,又不能使用外部跟踪工具(比如JProfiler……)的情况下,以上的这些参数就会发挥重大作用了,比如dump堆信息、打印并发锁……
)
五、
jhat(JVM Heap Analysis Tool)
Jhat是用来分析dump文件的一个微型的HTTP/HTML服务器,它能将生成的dump文件生成在线的HTML文件,让我们可以通过浏览器进行查阅,然而实际中我们很少使用这个工具,因为一般服务器上设置的堆、栈内存都比较大,生成的dump也比较大,直接用jhat容易造成内存溢出,而是我们大部分会将对应的文件拷贝下来,通过其他可视化的工具进行分析。启用法如下:
Jhat {dump_file}
执行命令后,我们看到系统开始读取这段dump信息,当系统提示Server is ready的时候,用户可以通过在浏览器键入http://ip地址:7000进行查询。
我们可以看到刚才生成的dump文件有多大
我们来生成以下看看!
jhat yhj.dump
//……..
然后我们启动浏览器查看
我们可以看到,很详细的类信息都被抓了出来
六、
jstack(JVM Stack Trace for java)
Jstack用于JVM当前时刻的线程快照,又称threaddump文件,它是JVM当前每一条线程正在执行的堆栈信息的集合。生成线程快照的主要目的是为了定位线程出现长时间停顿的原因,如线程死锁、死循环、请求外部时长过长导致线程停顿的原因。通过jstack我们就可以知道哪些进程在后台做些什么?在等待什么资源等!其运行格式如下:
Jstack [option] vmid
相关的option和function如下表所示
Option
Function
-F
当正常输出的请求不响应时强制输出线程堆栈
-l
除堆栈信息外,显示关于锁的附加信息
-m
显示native方法的堆栈信息
示例:jstack -l 20445
从JDK1.5以后,java.lang.Thread类增加了一个getAllStackTraces()方法用于获取虚拟机中的StackTraceElement对象,使用这段代码我们可以通过很简单的代码获取对应JVM的信息,下面是一个简单的示例:
package com.yhj.monitor;
import java.util.Map;import java.util.Set;/**
* @Described:线程监控器
* @author YHJ create at 2012-3-26 下午05:20:18
* @FileNmae com.yhj.monitor.Threadmonitor.java
*/public class Threadmonitor {
public static void main(String[] args) {
Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
Set<Thread> set = map.keySet();
for(Thread thread : set){
System.out.println("检测到线程["+thread.getId()+":"+thread.getName()+"],线程详细信息:");
for(StackTraceElement trace:map.get(thread)){
System.out.println(trace);
}
}
}
}
一次运行结果如下:
如果我们把这个写入一个
web工程的一个监控页面上,一个小的监控线程的程序就有了, !
介绍了前面几个命令,大家也许还在担心如何记住这么多详细的参数,其实JDK为我们提供了更为强大的GUI的监控工具,囊括了上面所有的监控工具的功能,同时还增加了很多工具方便我们的故障分析与性能监控!
从JDK1.5开始,JDK加入了可视化监控工具Jconsole,而从JDK1.6u7以后加了了多功能于一体的可视化监控工具VisualVM。下面我们来逐一看一下!
一、JConsole(JVM Monitoring and management console)
在JDK的bin目录下,我们很容易找到jconsole.exe这个程序,双击即可启动!
这款工具既可以实现本地监控,亦可以实现远程监控
.
启动后界面如图所示:
我们可以清楚的查看对应的CPu、内存、类和一起其他的详细信息。
在内存的tab页面,我们可以看到内存的变化。
在线程tab,我们可以追踪对应线程的变化情况
我们来监控一段代码:
package com.yhj.monitor;/**
* @Described:死锁演示
* @author YHJ create at 2012-3-26 下午05:46:36
* @FileNmae com.yhj.monitor.Deadlock.java
*/public class Deadlockimplements Runnable{
private int a;
private int b;
public Deadlock(int a,int b) {
super();
this.a = a;
this.b = b;
}
@Override
public void run() {
synchronized (Integer.valueOf(a)) {
synchronized (Integer.valueOf(b)) {
System.out.println("a+b="+(a+b));
}
}
}
public static void main(String[] args) {
for(int i = 0; i < 1000; ++i){
new Thread(new Deadlock(1, 2)).start();
new Thread(new Deadlock(2, 1)).start();
}
}
}
这段代码执行一段时间你会发现他不动了,如下图所示:
我们使用Jconsole的线程tab,下面有一个检测死锁的按钮,点击一下
Jconsole很清楚的告诉我们发生了死锁,如上图所示。并且明确的告诉我们死锁线程每个线程都在干什么?什么资源导致了死锁的发生,很精确。
很多人还在迷惑,上段代码怎么可能发生死锁的?每个线程独享一个a和一个b,互不相干,怎么可能发生死锁呢?
其实发生死锁的原因是我们调用了Integer.valueOf()方法,这个方法是基于减少创建对象次数和节省内存设计的,出于这个的考虑,在[-128~127]之间的数字会被缓存掉,也就是我们循环中传输了那么多的1和2其实就返回的2个,当某个对象持有1,而另外一个对象持有2的时候,第一个等待2的释放,而第二个等待1的释放,因此就发生了死锁。其实这个程序的循环也是不需要的,2个线程就可能引发死锁,但是程序执行太快,概率太小,加一个1000次的循环就是为了增大这种概率。
二、VisualVM
VisualVM被成为是more in one的工具集,它可以实现以下功能点:
1、 显示虚拟机的进程以及进程的配置信息和环境信息(jps、jinfo)
2、 监视应用程序的CPU、内存、堆、方法区和线程信息(jstat、jstack)
3、 Dump以及分析dump的功能(jmap、jhat)
4、 离线程序快照:离线dump分析
5、 方法运行性能分析,找出调用最多,运行最长的方法块
6、 Plugings动态扩展功能
VisualVM因为是基于netBean开发,因此天生就具有plug大量扩展的能力,我们可以通过他的插件页面轻松安装所需要的插件!
启用VisualVM工具会很醒目的告诉我们检测到一个死锁,而不需要我们在Jconsole下手动启用检测。如下图所示:
VisualVM
的插件安装图示如下图所示:
在VisualVM中有一个开源的,强大的插件,叫做BTrace。这是一个很有意思的插件,假设这么一种场景,某天你的程序突然出现了某个差错,但是有没有写日志,怎么办呢?BTrace就可以通过简单的代码注入,在你不重启服务器的情况下动态加入相关的日志语句。相关示例请参见官方DEMO:https://hg.kenai.com/hg/btrace~hg/file/d31d25ebd48b/samples。
- jvm监控
- JVM 监控
- JVM 监控
- JVM监控
- JVM监控
- JVM监控
- JVM监控
- jvm监控
- JVM内存监控:VisualVM远程监控JVM
- JVM内存监控:VisualVM远程监控JVM
- jvm相关监控工具
- JVM内存监控、分析
- JVM监控----积累中
- 【转】远程监控JVM
- JVM 性能监控
- 运用Jconsole监控JVM
- 远程监控JVM--VisualVM
- JVM监控工具介绍
- RecycleView 有下拉刷新情况下实现悬浮框效果
- 关于 "Android开发中More than file was fount..."的解决办法
- 分享个人学习和解决问题的的方法
- 欢迎使用CSDN-markdown编辑器
- ubuntu sudo update与upgrade的作用及区别
- jvm监控
- kafka系列-kafka调优篇-高并发高吞吐架构设计
- C# 获取系统时间及时间格式
- java项目经验面试总结
- Tesseract应用:ScrollView.jar以及ViewDebugging的使用及相关问题
- jsp复选框checkbox----表单处理
- Android开发JDK配置环境变量
- Java实现邮箱验证码
- 使用Microsoft的ClickOnce发布版本及网页更新版本