JVM全文
概述
- 调优
- 防止出现OOM
- 解决OOM
- 减少Full GC出现的频率
- 方向
- 合理编写代码
- 充分并合理地使用硬件资源
- 合理地进行JVM调优
- 监控依据
- 运行日志
- 异常堆栈
- GC日志
- 线程快照
- 堆转储快照
性能优化的步骤
- 性能监控,GC频繁;CPU load过高;OOM;内存泄漏;死锁;程序响应时间较长
非强行或入侵方式收集或查看性能数据的活动
- 性能分析,打印GC日志、GCView分析日志信息;运用命令行工具、jstack、jmap、jinfo;dump出堆文件,内存分析工具;查看JVM状态
- 侵入的方式,主动收集运行性能数据的活动,影响吞吐量或响应性
- 通常在开发环境下进行
- 性能调优,适当增加内存,根据业务背景选择垃圾回收器;优化代码,控制内存使用;增加机器,分散节点压力;合理设置线程池线程数量;使用中间件提高效率,如redis缓存、消息队列
为了改善应用响应性或吞吐量而更改参数、源代码、属性配置
性能评价、测试指标
- 停顿时间、响应时间
- 提交请求和返回请求的响应之间使用的时间
- 暂停时间,垃圾回收过程中,程序的工作线程会被暂停
-XX:MaxGCPauseMillis
- 吞吐量,单位时间内完成的工作量,TPS,单位时间处理用户的请求数
- 垃圾回收中,运行用户代码的时间占总运行时间的比例
-XX:GCTimeRation=n- 1-1/(1+n)
- 并发数,同一时刻,对服务器有实际交互的请求数
- 内存占用,java堆区所占的内存大小
- 举例,高速公路
- 吞吐量,每天通过高速公路收费站的车辆的数量(收费站收取的高速费)
- 并发数,高速公路正在行驶的车辆的数目
- 响应时间,车速
- 并发数增加 -> 响应时间下降 -> 吞吐量上升 -> 响应时间越来越慢 -> 吞吐量反而下降
调优命令行工具
jps
- java process status,查询正在运行的虚拟机进程
- ID与操作系统的进程ID一致
jps [options] [hostid]
jps -q,只看到进程Id,优先显示,独立显示jps -l,全类名jps -m > jps.txt,查看运行时传递的相关参数jps -v,查看传递的JVM参数
-XX:-UsePerfData,关闭后,不能通过jps查看<hostid>: <hostname>[:<port>],远程查看,需要搭配jstated
jstat
- JVM Statistics Monitoring Tool,查看JVM统计信息,监视虚拟机各种运行状态信息,类装载、内存、垃圾回收、JIT编译
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
option
- 类装载
-class显示ClassLoader的相关信息,类装载、卸载数量、总空间、类装载所消耗的时间
- JIT编译相关
-compilerJIT编译器编译过的方法、耗时-printcompilation输出已经被JIT编译的方法
- 垃圾回收,通过OU参数,挑选多组最小的数据,如果最小值上升,老年代不能被回收的对象越来越多,存在内存泄漏问题
-gc显示于GC相关的堆信息,GCT为累加的时间-gccapacity显示内容与上一个基本相同,主要关注java堆各个区域的最大、最小空间-gctuil主要关注已使用空间占总空间的百分比-gccause导致最后一次或当前正在发生的GC产生的原因;GCC正在发生GC的原因-gcnew显示新生代GC状况-gcnewcapacity主要关注使用到的最大、最小空间-geold显示老年代GC状况-gcoldcapacity主要关注使用到的最大、最小空间-gcpermcapacity显示永久代使用的最大、最小空间
-t和-h
- -t,程序开始执行到现在的时间,结合gc使用,可以计算出gc时间占运行时间的比例
jstat -class -t 85198- -h,在周期性数据输出时,输出表头数据
jstat -class -t -h3 85198 2000 10
每输出三条数据,重新打印表头
interval和count
- interval,
查询间隔,用于指定输出统计数据的周期,单位为毫秒 jstat -class 85198 2000- count,查询的总次数
jstat -class 85198 2000 10
查询id为85198的类装载情况,每隔2秒查询一次,共10次
jinfo
- Configuration Info for Java
- 查看虚拟机配置参数信息,调整虚拟机的配置参数
jinfo <option> <pid>
查看
-sysprops查看系统参数-flags查看被赋过值的参数
jdk16
jdk8
-flag查看执行参数
修改
- 只能立即修改被标记为
manageable的参数 java -XX:+PrintFlagsFinal -version | grep manageable查看可以修改的- 修改,使用
+/-修改,针对jdk8 - 修改值类型
拓展
java -XX:+PrintFlagsInitial查看所有JVM参数启动的初始值java -XX:+PrintFlagsFinal查看所有JVM参数的最终值java -XX:+PrintCommandLineFlags查看已经被用户或者JVM设置过的详细的参数名称和值
jmap
- JVM Memory Map
- 导出内存映像文件以及内存使用情况
- 获取dump文件(堆转储快照文件,保存堆情况),获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等
- 为了保证此过程不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态,导出的dump文件必定是安全点位置,有所偏差
dump
- JProfiler打开
- java进程在某个时间点的内存快照,输出之前会触发一次full gc,保存的是gc后的内存映像信息,不能连续监测
- 手动,根据实际情况选择
jmap -dump:format=b,file=/Users/apple/Desktop/java/jvm/test.hprof 86785,format匹配格式jmap -dump:live,format=b,file=/Users/apple/Desktop/java/jvm/test1.hprof 86785,live只保存堆中的存活对象
- 自动生成,发生OOM,自动导出dump文件
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/apple/Desktop/java/jvm/test2.hprof
显示堆内存信息
- 当前时刻堆占用情况
jmap -heap 22635 > /home/server/current/a.txt
- 内存空间详细对象情况
jmap -histo 22635 > /home/server/current/histo.txt
jmap -finalizerinfo 22635查看堆积在finalizer队列中的对象
jhat
- JVM Heap Analysis Tool
- 配合jmap的分析工作
- jdk9之后被删除,下面演示linux
jhat test.hprof,端口7000,生成分析的界面的相关信息-stack false|true是否打开对象分配调用栈跟踪-refs false|true是否打开对象引用跟踪-port port-number设置端口-exclude exclude-file对象查询排除的数据成员-baseline exclude-file指定一个基准堆转储
jstack
- JVM Stack Trace
- 用于生成虚拟机指定线程当前时刻的线程快照,显示各个线程调用的堆栈情况
- 线程状态,死锁、等待资源、等待获取同步监视器、阻塞、执行中、暂停、对象等待中、停止
jstack 92328jstack -l 92328,锁信息- java代码追踪栈信息
Map<Thread, StackTraceElement[]> all = Thread.getAllStackTraces();
Set<Map.Entry<Thread, StackTraceElement[]>> entries = all.entrySet();
for (Map.Entry<Thread, StackTraceElement[]> entry : entries) {
Thread key = entry.getKey();
StackTraceElement[] value = entry.getValue();
System.out.println("Tread name is :" + key.getName());
for (StackTraceElement stackTraceElement : value) {
System.out.println("\t" + stackTraceElement.toString());
}
}
jcmd
- 实现除了jstat之外的所有命令的功能
jcmd -l列出所有进程,类似jps -mjcmd 93061 help,指定进程支持的所有命令jcmd 93061 Thread.print打印线程信息,类似jstackjcmd 93061 GC.class_histogram内存对象详情,类似jmap -histojcmd 93061 GC.heap_dump /Users/apple/Desktop/java/jvm/d.hprof生成dump文件jcmd 93061 VM.uptime执行的时间jcmd 93061 VM.system_propertiesjvm系统属性
jstatd
- 远程监控,相当于代理服务器,建立本地计算机与远程监控工具的通信