首页 > 自考资讯 > 自考知识

常用的 jvm 调优的参数都有哪些?,jvm性能监控指标

头条共创 2024-07-05

在现实的企业级Java开发中,你可能会遇到如下问题:

OutOfMemoryError、内存不足、内存泄漏、线程死锁、锁争用、Java进程消耗过多CPU……这些问题在日常开发中可能被很多人忽略(比如有些人就遇到了上面提到的问题)。请重新启动服务器或增加内存,不要深究问题的根本原因)。然而,理解并能够解决这些问题是一个Java程序员进步的必要要求。本文介绍了一些常用的JVM 性能调优和监控工具,希望能提供一个有用的起点。本文参考了网上很多资料,但很难一一列举。我们谨向这些材料的作者表示感谢。有关JVM 性能调优的信息,请参阅文章末尾。

A.jps(Java虚拟机进程状态工具)

jps 主要用于打印JVM 中运行的进程的状态信息。语法格式为:

jps [options] [hostid] 如果不指定hostid,则默认使用当前主机或服务器。

命令行参数选项如下所述。

-q 不打印类名、Jar 名和传递给main 方法的参数。 -m 打印传递给main 方法的参数。 -l 打印主类或Jar 的完全限定名称。 -v 打印传递给JVM 的参数。像这样:

root@ubuntu:/# jps -m -l2458 org.artifactory.standalone.main.Main /usr/local/artifactory-2.2.5/etc/jetty.xml29920 com.sun.tools.hat.Main -端口9998 /tmp/dump.dat3149 org.apache.catalina.startup.Bootstrap start30972 sun.tools.jps.Jps -m -l8247 org.apache.catalina.startup.Bootstrap start25687 com.sun.tools.hat.Main -端口9999 dump.dat21711 mrf -center.jarB,jstack

jstack主要用于显示Java进程内的线程堆栈信息。语法格式为:

jstack [options] pidjstack [options]executable corejstack [options] [server-id@]remote-hostname-or-ip 命令行参数选项说明如下。

-l 长列表。如果发生死锁,则打印附加锁定信息。您可以使用jstack -l pid 监视锁定状态。 -m 混合模式打印C/C++ 堆栈信息以及Java 堆栈信息。 (如native方法)jstack经常用于JVM的性能调优,因为它可以识别线程堆栈,并且可以根据堆栈信息识别特定代码。考虑一个例子,查找特定Java 进程中消耗CPU 最多的Java 线程,使用的命令包括ps、top、printf、jstack、grep 等。

第一步是查找已部署到服务器的Java 应用程序的名称。

root@ubuntu:/# ps -ef | grep mrf-center | grep -v greproot 21711 1 1 14:47 pts/3 00:02:10 java -jar mrf-center.jar 第二步是找到最昂贵的进程。对于CPU 线程,请使用ps -Lfp pid 或ps -mp pid -o THREAD、tid、time 或top -Hp pid。输出是:

05b6820960464c559fb88a50e2597dc7~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720751704&x-signature=Mj%2Fa5h6wN4TfGIW6DWDbcCAIHBI%3D TIME列是每个Java线程消耗的CPU时间。 CPU 时间最长的是线程ID 21742 的线程。

printf '%x\n' 21742 获取21742 的十六进制值54ee。下面将用到这个。

下一步是jstack。这将打印进程21711 的堆栈信息,并根据线程ID 的十六进制值运行grep,如下所示:

root@ubuntu:/# jstack 21711 | grep 54ee'PollIntervalRetrySchedulerThread' prio=10 tid=0x00007f950043e000 nid=0x54ee in Object.wait() [0x00007f94c6eda000] CPU消耗是PollIntervalRetrySchedulerThread类Object你可以检查一下。 wait(),下载你找到的代码并找到以下代码。

//空闲waitgetLog().info('Thread [' + getName() + '] 正在等待空闲.');schedulerThreadState=PollTaskSchedulerThreadState.IdleWaiting;long now=System.currentTimeMillis( );long waitTime=now + getIdleWaitTime ();long timeUntilContinue=waitTime - now;synchronized(sigLock) {try { if(!halted.get()) { sigLock.wait(timeUntilContinue); } } catch (InterruptedExceptionignore) { } } 用于轮询任务Idle等待代码中,上面的sigLock.wait(timeUntilContinue)对应的是前面的Object.wait()。

C.jmap(内存映射)和jhat(Java堆分析工具)

jmap用于检查堆内存使用情况,通常与jhat结合使用。

jmap的语法格式为:

jmap [options] pidjmap [options] 可执行corejmap [options] [server-id@]remote-hostname-or-ip 如果您在64 位JVM 上运行,则必须指定-J-d64 命令选项参数。可能是个案。

jmap -permstat pid 打印有关进程的类加载器和类加载器加载的持久生成对象的信息。 输出:类加载器名称、对象是否存活(不可信)、对象地址、父类加载器、加载的类大小等。信息如下所示:

ac5903570ca94e5c85e0f8800170224c~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720751704&x-signature=nBYW4tMoVfcSVaky56r5C4zkDDc%3D 使用jmap -heap pid 查看进程的堆内存使用情况,包括使用的GC 算法、堆配置参数以及每代的堆内存使用情况。例如:

root@ubuntu:/# jmap -heap 21711 连接到进程ID 21711。请稍候. 调试器连接成功。检测到服务器编译器。 JVM 版本是20.10-b01。使用线程本地对象分配。 4线程并行GC堆配置: MinHeapFreeRatio=40 MaxHeapFreeRatio=70 MaxHeapSize=2067791872 (1972.0MB) NewSize=1310720 (1.25MB) MaxNewSize=17592186044415 MB OldSize=5439488 (5.187 5 MB) NewRatio=2 SurvivorRatio=8 PermSize=2175795 2 ( 20.75 MB) MaxPermSize=85983232 (82.0MB) 堆使用量:PS Young GenerationEden Space: 容量=6422528 (6.125MB) 已用=5445552 (5.1932830810546875MB) 可用=976976 (0.93171691 89453125MB) ) 84.78829520089286% 已用空间3 至360 容量=131072 (0.125MB)已用=98304 (0.09375MB) 可用=32768 (0.03125) MB ) 75.0% 已用到Space: 容量=131072 (0.125MB) 已用=0 (0.0MB) 可用=131072 (0.125MB) 0.0% 已用PS 老一代容量=35258368 ( 33.625MB) 已用=4119544 (3.9287033081054688MB) 可用=3 1138824 (29.69629669189453 MB) 11.683876009235595%usedPS 永久生成容量=524 28800 (50.0MB) 已用=2607 5168 (24.867218017578125MB) 免费=26353632 (25.1327819824218) 75MB) 49.734436035 已使用15625% . 查看数量使用jmap -histo[:live] pid 堆内存中的对象数量,大小统计直方图,如果带入live: 只统计存活对象,例如.

root@ubuntu:/# jmap -histo:live 21711 | 更多#instances #bytes 类名-------------------------------- - ------------- 1: 38445 5597736 constMethodKlass 2: 38445 5237288 方法类3: 3500 3749504 常量池类4: 60858 3242600 符号类5: 3500 271 4 实例类6: 2796 2131424 常量池缓存类7: 5543 1317400 [I 8: 13714 1010768 [C 9:] 4752 1003344 [B 10: 1225 639656 方法数据类11: 14194 454208 java.lang.String 12: 3809 3 96136 java.lang.Class 13: 4979 311952 [S 143336 0 559 8 287064 [[I 15: 3028 266464 java.lang.reflect.Method 16: 280 163520 objArrayKlassKlass 17: 4355 139360 java.util.HashMap$Entry 18: 1869 138568 [Ljava.util.HashMap$Entry 0 1807 71528 [Ljava.lang.Object; 22: 2206 70592 java.lang .ref.WeakReference; 934 52304 java.util.LinkedHashMap 24: 871 48776 java.beans.MethodDescriptor 25: 1442 46144 java.util.concurrent.ConcurrentHashMap$ HashEntry 26: 804 92 java.util.HashMap 27:第948章37920 ashMap$段28: 1621 35696 [Ljava.lang.Class; 29: 1313 34880 [Ljava.lang.String; 30: 1396 33504 java.util.LinkedList$Entry 31: 462 33264 3360 1024 32768 java.util。 Hashtable$Entry 3333 360 948 31440 [Ljava.util.concurrent.ConcurrentHashMap$HashEntry; 类名是对象类型,描述是:

B byteC charD doubleF floatI intJ longZ boolean[ 数组,[I 表示int[][L+类名,其他对象。 ] 另一种很常见的情况是使用jmap将进程内存使用情况转储到文件中,然后使用jhat执行以下操作:分析并展示。 jmap执行的dump命令格式为:

jmap -dump:format=b,file=dumpFileName pid 我对上面的进程ID 21711 运行了相同的转储。

root@ubuntu:/# jmap -dump:format=b,file=/tmp/dump.dat 21711 Dumping heap to /tmp/dump.dat .创建的堆转储文件转储的文件是可以使用MAT 等工具查看视觉虚拟机。这里我们使用jhat来显示它。

root@ubuntu:/# jhat -port 9998 /tmp/dump.datReading from /tmp/dump.dat.转储文件创建于Tue Jan 28 17:46:14 读取CST 2014 快照,解决.正在解决132207 个对象.跟踪引用,预计26 点.重复引用删除...快照已解决。在端口9998 上启动的HTTP 服务器现已准备就绪。如果转储文件太大,您可能需要添加一个参数,例如-J-Xmx512m 来指定最大堆内存。即jhat -J-Xmx512m -port 9998 /tmp/dump.dat。然后在浏览器中输入主机地址:9998,你会看到以下内容:

e9a33c6475764b1e8a705e649d706889~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720751704&x-signature=wWqYQsGuwapiQTiJlFT4H%2BemJDc%3D 上图红框内部分您可以自行查看。最后一项支持OQL(对象查询语言)。

D.jstat(JVM统计监控工具)

语法格式为:

jstat [generalOption |outputOptions vmid [interval[s|ms] [count]] ] vmid 是Java 虚拟机ID,通常是Linux/Unix 系统上的进程ID。 Interval是采样时间间隔。 count 是样本数。例如,下面输出的是采样间隔为250ms、采样数为4的GC信息。

root@ubuntu:/# jstat -gc 21711 250 4 S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT 192.0 192.0 64.0 0.0 6144.0 1854.9 32000.0 4111.6 55296.0 4 7 2.7 702 0.431 3 0.218 0.649192.0 192.0 64.0 0.0 6144.0 1972.2 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 0.649192.0 192.0 64.0 0.0 6144.0 1972.2 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 0.649192.0 192.0 64.0 0.0 6144.0 2109.7 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 0.649 要了解以上各列的含义,首先,看一下JVM堆内存布局。

658cd5b058c54b9d8f73643dfcbee3c9~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720751704&x-signature=AasMRIp1XWTo02Z%2FA5WGGETb8VI%3D 您将看到以下内容:

堆内存=年轻代+老年代+持久代年轻代=伊甸园空间+两个幸存者空间(From和To)接下来,我们将解释每一列的含义。

S0C、S1C、S0U、S1U:Survivor 0/1 区域的容量和使用量EC、EU:Eden 区域的容量和使用量OC、OU:上一代的容量和使用量PC、PU:永久代容量和使用量YGC 、YGT:年轻代GC时间和GC消耗时间FGC、FGCT:完整GC时间和完整GC消耗时间GCT:总GC消耗时间E、hprof(堆/CPU分析工具)

hprof可以显示CPU使用情况并统计堆内存使用情况。

语法格式为:

java -agentlib:hprof[=options] ToBeProfiledClassjava -Xrunprof[:options] ToBeProfiledClassjavac -J-agentlib:hprof[=options] ToBeProfiledClass 完整的命令选项为:

选项名称和值说明默认----------- ----------- ----------heap=dump|sites |所有堆分析allcpu=samples|times |旧的CPU 使用率offmonitor=y|n 监视争用nformat=a|b 文本(txt) 或二进制输出afile=file 将数据写入文件java.hprof[.txt]net=host:port 发送套接字上的数据关闭深度=大小堆栈跟踪深度4interval=ms 采样间隔(ms) 10cutoff=值输出截止点0.0001lineno=y|n 跟踪中的行号ythread=y|n 线程中的转储? ysa=y|n Solaris 微状态记帐nforce=y|n 强制输出到文件yverbose=y|n 打印有关转储的消息y 以下是官方指南中的一些示例:

CPU 使用情况采样分析示例(cpu=samples):

java -agentlib:hprof=cpu=样本,间隔=20,深度=3 你好。 CPU 消耗信息每20 毫秒采样一次。堆栈深度为3。生成的配置文件的名称是java.hprof.txt。当前目录。

CPU 使用时间分析示例(cpu=times)。与CPU 使用率采样配置文件相比,您可以获得更详细的CPU 消耗信息,甚至包括每个方法调用的开始和结束。脑机接口):

javac -J-agentlib:hprof=cpu=times Hello.java 堆分配分析示例(heap=sites):

javac -J-agentlib:hprof=heap=sites Hello.java 堆转储(heap=dump) 示例。它可以生成比上述堆分配分析更详细的堆转储信息。

javac -J-agentlib:hprof=heap=dump Hello.java 在JVM启动参数中添加-Xrunprof:heap=sites参数可以生成CPU/heap profile文件,但对JVM性能影响较大,不能用于在线服务器环境。

其他JVM性能调优参考:

《Java虚拟机规范》

《Java Performance》

《Trouble Shooting Guide for JavaSE 6 with HotSpot VM》 : http://www.oracle.com/technetwork/java/javase/tsg-vm-149989.pdf

《Effective Java》

VisualVM: http://docs.oracle.com/javase/7/docs/technotes/guides/visualvm/

jConsole: http://docs.oracle.com/javase/1.5.0/docs/guide/management/jconsole.html

监视和管理JavaSE 6 应用程序: http://www.oracle.com/technetwork/articles/javase/monitoring-141801.html

BTrace:https://kenai.com/projects/btrace

版权声明:本文转载于今日头条,版权归作者所有。如有侵权,请联系本站编辑删除。

猜你喜欢