JVM(Java虚拟机)调优是优化Java应用程序性能和内存使用的过程。调优可以帮助应用程序更有效地利用内存、提高吞吐量和降低延迟。
JVM 调优的参数都有哪些?
对于JVM调优,主要就是调整年轻代、老年代、元空间的内存空间大小及使用的垃圾回收器类型。
www.oracle.com/java/techno…
- 设置堆空间大小
- 虚拟机栈的设置
- 年轻代中Eden区和两个Survivor区的大小比例
- 年轻代晋升老年代阈值
- 设置垃圾回收收集器
设置堆空间大小
设置堆的初始大小和最大大小,为了防止垃圾收集器在初始大小、最大大小之间收缩堆而产生额外的时间,通常把最大、初始大小设置为相同的值。
不指定单位默认为字节,指定单位,按照指定的单位设置
堆空间设置多少合适?
- 最大大小的默认值是物理内存的1/4,初始大小是物理内存的1/64
- 堆太小,可能会频繁的导致年轻代和老年代的垃圾回收,会产生stw,暂停用户线程
- 堆内存大肯定是好的,存在风险,假如发生了fullgc,它会扫描整个堆空间,暂停用户线程的时间长
- 设置参考推荐:尽量大,也要考察一下当前计算机其他程序的内存使用情况
虚拟机栈的设置
虚拟机栈的设置:每个线程默认会开启1M的内存,用于存放栈帧、调用参数、局部变量等,但一般256K就够用。通常减少每个线程的堆栈,可以产生更多的线程,但这实际上还受限于操作系统。
年轻代中Eden区和两个Survivor区的大小比例
设置年轻代中Eden区和两个Survivor区的大小比例。该值如果不设置,则默认比例为8:1:1。通过增大Eden区的大小,来减少YGC发生的次数,但有时我们发现,虽然次数减少了,但Eden区满的时候,由于占用的空间较大,导致释放缓慢,此时STW的时间较长,因此需要按照程序情况去调优。
年轻代晋升老年代阈值
默认为15;取值范围0-15
设置垃圾回收收集器
通过增大吞吐量提高系统性能,可以通过设置并行垃圾回收收集器。
JVM的调优工具
命令工具
- jps 进程状态信息
- jstack 查看java进程内线程的堆栈信息
- jmap 查看堆转信息
- jhat 堆转储快照分析工具
- jstat JVM统计监测工具
可视化工具
- jconsole 用于对jvm的内存,线程,类的监控
- VisualVM 能够监控线程,内存情况
jps
作用:查看进程状态信息
jstack
作用:查看java进程内线程的堆栈信息
jmap
作用:用于生成堆转内存快照、内存使用情况
- format=b表示以hprof二进制格式转储Java堆的内存
- file=用于指定快照dump文件的文件名。
它是一个进程或系统在某一给定的时间的快照。比如在进程崩溃时,甚至是任何时候,我们都可以通过工具将系统或某进程的内存备份出来供调试分析用。dump文件中包含了程序运行的模块信息、线程信息、堆栈调用信息、异常信息等数据,方便系统技术人员进行错误排查。
jstat
是JVM统计监测工具。可以用来显示垃圾回收信息、类加载信息、新生代统计信息等。
总结垃圾回收统计(jstat -gcutil pid
)
垃圾回收统计(jstat -gc pid
)
jconsole
用于对jvm的内存,线程,类 的监控,是一个基于 jmx 的 GUI 性能监控工具
打开方式:java 安装目录 bin目录下 直接启动 jconsole.exe 就行
VisualVM
能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的对象,反向查看分配的堆栈
打开方式:java 安装目录 bin目录下 直接启动 jvisualvm.exe就行
JVM内存泄漏的排查思路
以微服务项目为例,现有服务如下:
目前存在问题:启动闪退;运行一段时间宕机。
解决方法
1. 获取堆内存快照dump
通过jmap指定打印他的内存快照dump(Dump文件是进程的内存镜像。可以把程序的执行状态通过调试器保存到dump文件中)
-
使用jmap命令获取运行中程序的dump文件
(jmap -dump:format=b,file=heap.hprof pid
) -
使用vm参数获取dump文件:有的情况是内存溢出之后程序则会直接中断,而jmap只能打印在运行中的程序,所以建议通过参数的方式的生成dump文件
2.通过工具, VisualVM去分析dump文件,VisualVM可以加载离线的dump文件
文件-->装入--->选择dump文件即可查看堆快照信息
3.通过查看堆信息的情况,可以大概定位内存溢出是哪行代码出了问题
4.找到对应的代码,通过阅读上下文的情况,进行修复即可
CPU飙高排查方案与思路
通过top命令查看后,可以查看是哪一个进程占用cpu较高,上图所示的进程为:40940
查看进程中的线程信息。(ps H -eo pid,tid,%cpu | grep pid
)
通过以上分析,在进程40940中的线程40950占用cpu较高
printf "%xn" 40955
。jstack pid
)总结(简介版)
参考
B站:黑马程序员