首页 > 编程知识 正文

怎样远程监测jvm(jvm常用调优)

时间:2023-05-03 05:03:23 阅读:90884 作者:2691

作者|优雅先生

资料来源| my.oschina.net/feichexia/blog/196575

在企业级的Java APP开发、维护中,有时会出现以下问题。

OutOfMemoryError、内存不足内存泄漏导致的线程死锁竞争(Lock Contention ) Java进程的消耗CPU过高……这些问题在日常开发、维护中可能被许多人忽视。 有些人面对上述问题也只是重启服务器,增大内存,而不会深究问题的根本原因),但能理解和解决这些问题的是Java程序员的正文常用的JVM性能监控工具。

而且,这些监视、调整工具的使用,无论是运输、开发、测试,都必须掌握。

a、jps (javavirtualmachineprocessstatustool )。

jps主要用于输出在JVM上运行的进程的状态信息。 语法如下:

如果不指定JPS[options][hostid]hostid,则默认情况下为当前主机或服务器。

以下说明命令行选项。

b、jstack

jstack主要用于显示Java进程中的线程堆栈信息。 语法如下:

jstack在JVM性能调优中使用得非常多,因为它可以放置在线程堆栈中,并且可以基于堆栈信息放置在特定的代码中。 让我们来看看在某个Java进程中找到最占用CPU的Java线程并搜索堆栈信息的示例。 要使用的命令是ps、top、printf、jstack和grep。

第一步是首先找到Java进程ID。 部署在伺服器上的Java APP应用程式名称为mrf-center。

root @ Ubuntu :/# PS-ef |组射频-中心|组- v组

在root 21711114336047 pts/300336002336010 Java-jar MRF-center.jar中获得的进程ID为21711,在第二步中,我们将在该进程中找到最消耗CPU的线程

TIME列是各Java线程所消耗的CPU时间,CPU时间最长的是线程ID为21742的线程

由printf '%xn' 21742获得的21742的十六进制值为54ee,用于以下目的:

OK,下一步终于轮到jstack出场了。 它用于输出进程21711的堆栈信息,并根据线程ID的十六进制值进行分组,如下所示:

根@ Ubuntu :/# jstack 21711 |组54e e

' Pollintervalretryschedulerthread ' Prio=10 TID=0x 00007 f 950043 e 000 NID=0x 54 EIN对象. Wait ([0x 0007 f 94 c6EDA 000 ]为

这是轮询任务的空闲等待代码,上面的siglock.wait(timeuntilcontinue )与前面的Object.wait相对应。

c、jhat (内存映射)和jhat (日本航空公司) )。

jmap用于显示堆内存的使用情况,通常与jhat结合使用。

jmap语法的格式如下:

地图PID

jmap可执行核心

在jmap [ option ] [服务器id @ ]远程主机名或ip64位JVM上运行时,可能需要指定-J-d64命令选项参数。

jmap -permstat pid打印进程的类加载器和类加载器加载的永久对象信息。 输出:类加载器名称、对象是否存在(是否不可靠)、对象地址、父类加载器、已加载

的类大小等信息,如下图:

使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。比如下面的例子:

使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象,如下:

class name是对象类型,说明如下:

B byte C char D double F float I int J long Z boolean [ 数组,如[I表示int[] [L+类名 其他对象

还有一个很常用的情况是:用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。jmap进行dump命令格式如下:

jmap -dump:format=b,file=dumpFileName pid

我一样地对上面进程ID为21711进行Dump:

root@ubuntu:/# jmap -dump:format=b,file=/tmp/dump.dat 21711 Dumping heap to /tmp/dump.dat ... Heap dump file created

dump出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看:

注意如果Dump文件太大,可能需要加上-J-Xmx512m这种参数指定最大堆内存,即jhat -J-Xmx512m -port 9998 /tmp/dump.dat。然后就可以在浏览器中输入主机地址:9998查看了:

上面红线框出来的部分大家可以自己去摸索下,最后一项支持OQL(对象查询语言)。

D、jstat(JVM统计监测工具)

语法格式如下:

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

vmid是Java虚拟机ID,在Linux/Unix系统上一般就是进程ID。interval是采样时间间隔。count是采样数目。比如下面输出的是GC信息,采样时间间隔为250ms,采样数为4:

要明白上面各列的意义,先看JVM堆内存布局:

可以看出:

堆内存 = 年轻代 + 年老代 + 永久代 年轻代 = Eden区 + 两个Survivor区(From和To)

现在来解释各列含义:

S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used) EC、EU:Eden区容量和使用量 OC、OU:年老代容量和使用量 PC、PU:永久代容量和使用量 YGC、YGT:年轻代GC次数和GC耗时 FGC、FGCT:Full GC次数和Full GC耗时 GCT:GC总耗时

E、hprof(Heap/CPU Profiling Tool)

hprof能够展现CPU使用率,统计堆内存使用情况。

语法格式如下:

java -agentlib:hprof[=options] ToBeProfiledClass java -Xrunprof[:options] ToBeProfiledClass javac -J-agentlib:hprof[=options] ToBeProfiledClass

完整的命令选项如下:

来几个官方指南上的实例。

CPU Usage Sampling Profiling(cpu=samples)的例子:

java -agentlib:hprof=cpu=samples,interval=20,depth=3 Hello

上面每隔20毫秒采样CPU消耗信息,堆栈深度为3,生成的profile文件名称是java.hprof.txt,在当前目录。

CPU Usage Times Profiling(cpu=times)的例子,它相对于CPU Usage Sampling Profile能够获得更加细粒度的CPU消耗信息,能够细到每个方法调用的开始和结束,它的实现使用了字节码注入技术(BCI):

javac -J-agentlib:hprof=cpu=times Hello.java

Heap Allocation Profiling(heap=sites)的例子:

javac -J-agentlib:hprof=heap=sites Hello.java

Heap Dump(heap=dump)的例子,它比上面的Heap Allocation Profiling能生成更详细的Heap Dump信息:

javac -J-agentlib:hprof=heap=dump Hello.java

虽然在JVM启动参数中加入-Xrunprof:heap=sites参数可以生成CPU/Heap Profile文件,但对JVM性能影响非常大,不建议在线上服务器环境使用。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。