搭建网站平台,曲靖seo,哪家公司建立5g散热工业园,网络服务怎么写18.1. 概述
性能诊断是软件工程师在日常工作中需要经常面对和解决的问题#xff0c;在用户体验至上的今天#xff0c;解决好应用的性能问题能带来非常大的收益。
Java 作为最流行的编程语言之一#xff0c;其应用性能诊断一直受到业界广泛关注。可能造成 Java 应用出现性能…18.1. 概述
性能诊断是软件工程师在日常工作中需要经常面对和解决的问题在用户体验至上的今天解决好应用的性能问题能带来非常大的收益。
Java 作为最流行的编程语言之一其应用性能诊断一直受到业界广泛关注。可能造成 Java 应用出现性能问题的因素非常多例如线程控制、磁盘读写、数据库访问、网络I/O、垃圾收集等。想要定位这些问题一款优秀的性能诊断工具必不可少。
体会1使用数据说明问题使用知识分析问题使用工具处理问题。
体会2无监控、不调优
简单命令行工具
在我们刚接触java学习的时候大家肯定最先了解的两个命令就是javacjava那么除此之外还有没有其他的命令可以供我们使用呢
我们进入到安装jdk的bin目录发现还有一系列辅助工具。这些辅助工具用来获取目标 JVM 不同方面、不同层次的信息帮助开发人员很好地解决Java应用程序的一些疑难杂症。 官方源码地址http://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/jdk.jcmd/share/classes/sun/tools
18.2. jps查看正在运行的Java进程
jps(Java Process Status)显示指定系统内所有的HotSpot虚拟机进程查看虚拟机进程信息可用于查询正在运行的虚拟机进程。
说明对于本地虚拟机进程来说进程的本地虚拟机ID与操作系统的进程ID是一致的是唯一的。
基本使用语法为jps [options] [hostid]
我们还可以通过追加参数来打印额外的信息。
options参数
-q仅仅显示LVMIDlocal virtual machine id即本地虚拟机唯一id。不显示主类的名称等-l输出应用程序主类的全类名 或 如果进程执行的是jar包则输出jar完整路径-m输出虚拟机进程启动时传递给主类main()的参数-v列出虚拟机进程启动时的JVM参数。比如-Xms20m -Xmx50m是启动程序指定的jvm参数。
说明以上参数可以综合使用。
补充如果某 Java 进程关闭了默认开启的UsePerfData参数即使用参数-XX-UsePerfData那么jps命令以及下面介绍的jstat将无法探知该Java 进程。
hostid参数
RMI注册表中注册的主机名。如果想要远程监控主机上的 java 程序需要安装 jstatd。
对于具有更严格的安全实践的网络场所而言可能使用一个自定义的策略文件来显示对特定的可信主机或网络的访问尽管这种技术容易受到IP地址欺诈攻击。
如果安全问题无法使用一个定制的策略文件来处理那么最安全的操作是不运行jstatd服务器而是在本地使用jstat和jps工具。
18.3. jstat查看JVM统计信息
jstatJVM Statistics Monitoring Tool用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。在没有GUI图形界面只提供了纯文本控制台环境的服务器上它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。
官方文档https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html
基本使用语法为jstat - [-t] [-h] [ []]
查看命令相关参数jstat-h 或 jstat-help
其中vmid是进程id号也就是jps之后看到的前面的号码如下 option参数
选项option可以由以下值构成。
类装载相关的
-class显示ClassLoader的相关信息类的装载、卸载数量、总空间、类装载所消耗的时间等
垃圾回收相关的
-gc显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、已用空间、GC时间合计等信息。-gccapacity显示内容与-gc基本相同但输出主要关注Java堆各个区域使用到的最大、最小空间。-gcutil显示内容与-gc基本相同但输出主要关注已使用空间占总空间的百分比。-gccause与-gcutil功能一样但是会额外输出导致最后一次或当前正在发生的GC产生的原因。-gcnew显示新生代GC状况-gcnewcapacity显示内容与-gcnew基本相同输出主要关注使用到的最大、最小空间-gcold显示老年代GC状况-gcoldcapacity显示内容与-gcold基本相同输出主要关注使用到的最大、最小空间-gcpermcapacity显示永久代使用到的最大、最小空间。
JIT相关的
-compiler显示JIT编译器编译过的方法、耗时等信息-printcompilation输出已经被JIT编译的方法
jstat -class jstat -compiler jstat -printcompilation jstat -gc jstat -gccapacity jstat -gcutil jstat -gccause jstat -gcnew jstat -gcnewcapacity jstat -gcold jstat -gcoldcapacity jstat -t jstat -t -h 表头含义字节ECEden区的大小EUEden区已使用的大小S0C幸存者0区的大小S1C幸存者1区的大小S0U幸存者0区已使用的大小S1U幸存者1区已使用的大小MC元空间的大小MU元空间已使用的大小OC老年代的大小OU老年代已使用的大小CCSC压缩类空间的大小CCSU压缩类空间已使用的大小YGC从应用程序启动到采样时young gc的次数YGCT从应用程序启动到采样时young gc消耗时间秒FGC从应用程序启动到采样时full gc的次数FGCT从应用程序启动到采样时的full gc的消耗时间秒GCT从应用程序启动到采样时gc的总时间
interval参数 用于指定输出统计数据的周期单位为毫秒。即查询间隔
count参数 用于指定查询的总次数
-t参数 可以在输出信息前加上一个Timestamp列显示程序的运行时间。单位秒
-h参数 可以在周期性数据输出时输出多少行数据后输出一个表头信息
补充 jstat还可以用来判断是否出现内存泄漏。
第1步在长时间运行的 Java 程序中我们可以运行jstat命令连续获取多行性能数据并取这几行数据中 OU 列即已占用的老年代内存的最小值。
第2步然后我们每隔一段较长的时间重复一次上述操作来获得多组 OU 最小值。如果这些值呈上涨趋势则说明该 Java 程序的老年代内存已使用量在不断上涨这意味着无法回收的对象在不断增加因此很有可能存在内存泄漏。
18.4. jinfo实时查看和修改JVM配置参数
jinfo(Configuration Info for Java)查看虚拟机配置参数信息也可用于调整虚拟机的配置参数。在很多情况卡Java应用程序不会指定所有的Java虚拟机参数。而此时开发人员可能不知道某一个具体的Java虚拟机参数的默认值。在这种情况下可能需要通过查找文档获取某个参数的默认值。这个查找过程可能是非常艰难的。但有了jinfo工具开发人员可以很方便地找到Java虚拟机参数的当前值。
基本使用语法为jinfo [options] pid
说明java 进程ID必须要加上
选项选项说明no option输出全部的参数和系统属性-flag name输出对应名称的参数-flag [±]name开启或者关闭对应名称的参数 只有被标记为manageable的参数才可以被动态修改-flag namevalue设定对应名称的参数-flags输出全部的参数-sysprops输出系统属性
jinfo -sysprops jinfo -sysprops
jboss.modules.system.pkgs com.intellij.rt
java.vendor Oracle Corporation
sun.java.launcher SUN_STANDARD
sun.management.compiler HotSpot 64-Bit Tiered Compilers
catalina.useNaming true
os.name Windows 10
...jinfo -flags jinfo -flags 25592
Non-default VM flags: -XX:CICompilerCount4 -XX:InitialHeapSize333447168 -XX:MaxHeapSize5324668928 -XX:MaxNewSize1774714880 -XX:MinHeapDeltaBytes524288 -XX:NewSize111149056 -XX:OldSize222298112 -XX:UseCompressedClassPointers -XX:UseCompressedOops -XX:UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:UseParallelGC
Command line: -agentlib:jdwptransportdt_socket,address127.0.0.1:8040,suspendy,servern -Drebel.baseC:\Users\Vector\.jrebel -Drebel.env.ide.plugin.version2021.1.2 -Drebel.env.ide.version2020.3.3 -Drebel.env.ide.productIU -Drebel.env.ideintellij -Drebel.notification.urlhttp://localhost:7976 -agentpath:C:\Users\Vector\AppData\Roaming\JetBrains\IntelliJIdea2020.3\plugins\jr-ide-idea\lib\jrebel6\lib\jrebel64.dll -Dmaven.homeD:\eclipse\env\maven -Didea.modules.paths.fileC:\Users\Vector\AppData\Local\JetBrains\IntelliJIdea2020.3\Maven\idea-projects-state-596682c7.properties -Dclassworlds.confC:\Users\Vector\AppData\Local\Temp\idea-6755-mvn.conf -Dmaven.ext.class.pathD:\IDEA\plugins\maven\lib\maven-event-listener.jar -javaagent:D:\IDEA\plugins\java\lib\rt\debugger-agent.jar -Dfile.encodingUTF-8jinfo -flag jinfo -flag UseParallelGC 25592
-XX:UseParallelGC jinfo -flag UseG1GC 25592
-XX:-UseG1GCjinfo -flag name jinfo -flag UseParallelGC 25592
-XX:UseParallelGC jinfo -flag UseG1GC 25592
-XX:-UseG1GCjinfo -flag [±]name jinfo -flag PrintGCDetails 25592jinfo -flag PrintGCDetails 25592
-XX:PrintGCDetails jinfo -flag -PrintGCDetails 25592jinfo -flag PrintGCDetails 25592
-XX:-PrintGCDetails拓展
java -XX:PrintFlagsInitial 查看所有JVM参数启动的初始值
[Global flags]intx ActiveProcessorCount -1 {product}uintx AdaptiveSizeDecrementScaleFactor 4 {product}uintx AdaptiveSizeMajorGCDecayTimeScale 10 {product}uintx AdaptiveSizePausePolicy 0 {product}
...java -XX:PrintFlagsFinal 查看所有JVM参数的最终值
[Global flags]intx ActiveProcessorCount -1 {product}
...intx CICompilerCount : 4 {product}uintx InitialHeapSize : 333447168 {product}uintx MaxHeapSize : 1029701632 {product}uintx MaxNewSize : 1774714880 {product}java -XX:PrintCommandLineFlags 查看哪些已经被用户或者JVM设置过的详细的XX参数的名称和值
-XX:InitialHeapSize332790016 -XX:MaxHeapSize5324640256 -XX:PrintCommandLineFlags -XX:UseCompressedClassPointers -XX:UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:UseParallelGC18.5. jmap导出内存映像文件内存使用情况
jmapJVM Memory Map作用一方面是获取dump文件堆转储快照文件二进制文件它还可以获取目标Java进程的内存相关信息包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。开发人员可以在控制台中输入命令“jmap -help”查阅jmap工具的具体使用方式和一些标准选项配置。
官方帮助文档https://docs.oracle.com/en/java/javase/11/tools/jmap.html
基本使用语法为
jmap [option] jmap [option] executable jmap [option] [server_id]
选项作用-dump生成dump文件Java堆转储快照-dump:live只保存堆中的存活对象-heap输出整个堆空间的详细信息包括GC的使用、堆配置信息以及内存的使用信息等-histo输出堆空间中对象的统计信息包括类、实例数量和合计容量-histo:live只统计堆中的存活对象-J 传递参数给jmap启动的jvm-finalizerinfo显示在F-Queue中等待Finalizer线程执行finalize方法的对象仅linux/solaris平台有效-permstat以ClassLoader为统计口径输出永久代的内存状态信息仅linux/solaris平台有效-F当虚拟机进程对-dump选项没有任何响应时强制执行生成dump文件仅linux/solaris平台有效
说明这些参数和linux下输入显示的命令多少会有不同包括也受jdk版本的影响。 jmap -dump:formatb,filefilename.hprof pidjmap -dump:live,formatb,filefilename.hprof pid由于jmap将访问堆中的所有对象为了保证在此过程中不被应用线程干扰jmap需要借助安全点机制让所有线程停留在不改变堆中数据的状态。也就是说由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。
举个例子假设在编译生成的机器码中某些对象的生命周期在两个安全点之间那么:live选项将无法探知到这些对象。
另外如果某个线程长时间无法跑到安全点jmap将一直等下去。与前面讲的jstat则不同垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中而jstat只需直接读取即可。
18.6.自动生成 Heap Dump 文件
-XX:HeapDumpOnOutOfMemoryError 当OutOfMemoryError发生时自动生成 Heap Dump 文件。 当你需要分析Java内存使用情况时往往是在OOM(OutOfMemoryError)发生时。-XX:HeapDumpBeforeFullGC 当 JVM 执行 FullGC 前执行 dump。-XX:HeapDumpAfterFullGC 当 JVM 执行 FullGC 后执行 dump。-XX:HeapDumpOnCtrlBreak 交互式获取dump。在控制台按下快捷键Ctrl Break时JVM就会转存一下堆快照。-XX:HeapDumpPath/opt/logs/dumplogs 指定 dump 文件的存储路径
18.7. jhatJDK自带堆分析工具
jhat(JVM Heap Analysis Tool)Sun JDK提供的jhat命令与jmap命令搭配使用用于分析jmap生成的heap dump文件堆转储快照。jhat内置了一个微型的HTTP/HTML服务器生成dump文件的分析结果后用户可以在浏览器中查看分析结果分析虚拟机转储快照信息。
使用了jhat命令就启动了一个http服务端口是7000即http://localhost:7000/就可以在浏览器里分析。
说明jhat命令在JDK9、JDK10中已经被删除官方建议用VisualVM代替。
基本适用语法jhat
option参数作用-stack falsetrue关闭打开对象分配调用栈跟踪-refs falsetrue关闭打开对象引用跟踪-port port-number设置jhat HTTP Server的端口号默认7000-exclude exclude-file执行对象查询时需要排除的数据成员-baseline exclude-file指定一个基准堆转储-debug int设置debug级别-version启动后显示版本信息就退出-J 传入启动参数比如-J-Xmx512m
18.8. jstack打印JVM中线程快照
jstackJVM Stack Trace用于生成虚拟机指定进程当前时刻的线程快照虚拟机堆栈跟踪。线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。
生成线程快照的作用可用于定位线程出现长时间停顿的原因如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停顿时就可以用jstack显示各个线程调用的堆栈情况。
官方帮助文档https://docs.oracle.com/en/java/javase/11/tools/jstack.html
在thread dump中要留意下面几种状态
死锁Deadlock重点关注等待资源Waiting on condition重点关注等待获取监视器Waiting on monitor entry重点关注阻塞Blocked重点关注执行中Runnable暂停Suspended对象等待中Object.wait() 或 TIMEDWAITING停止Parked
option参数作用-F当正常输出的请求不被响应时强制输出线程堆栈-l除堆栈外显示关于锁的附加信息-m如果调用本地方法的话可以显示C/C的堆栈
18.9. jcmd多功能命令行
在JDK 1.7以后新增了一个命令行工具jcmd。它是一个多功能的工具可以用来实现前面除了jstat之外所有命令的功能。比如用它来导出堆、内存使用、查看Java进程、导出线程信息、执行GC、JVM运行时间等。
官方帮助文档https://docs.oracle.com/en/java/javase/11/tools/jcmd.html
jcmd拥有jmap的大部分功能并且在Oracle的官方网站上也推荐使用jcmd命令代jmap命令
**jcmd -l**列出所有的JVM进程
**jcmd 进程号 help**针对指定的进程列出支持的所有具体命令 **jcmd 进程号 具体命令**显示指定进程的指令命令的数据
Thread.print 可以替换 jstack指令GC.class_histogram 可以替换 jmap中的-histo操作GC.heap_dump 可以替换 jmap中的-dump操作GC.run 可以查看GC的执行情况VM.uptime 可以查看程序的总执行时间可以替换jstat指令中的-t操作VM.system_properties 可以替换 jinfo -sysprops 进程idVM.flags 可以获取JVM的配置参数信息
18.10. jstatd远程主机信息收集
之前的指令只涉及到监控本机的Java应用程序而在这些工具中一些监控工具也支持对远程计算机的监控如jps、jstat。为了启用远程监控则需要配合使用jstatd 工具。命令jstatd是一个RMI服务端程序它的作用相当于代理服务器建立本地计算机与远程监控工具的通信。jstatd服务器将本机的Java应用程序信息传递到远程计算机。