Java-jvm调优文档摘要

Java-jvm调优文档摘要

官方文档:https://docs.oracle.com/en/java/javase/16/gctuning/factors-affecting-garbage-collection-performance.html

关于官方文档的理解,jdk版本不同参数略有区别,特别是jdk1.8之后的改动,取消了永久代这个区域,1.8没有ZGC垃圾回收器,但jdk16的jvm中有ZGC垃圾收集器。

jvm为什么需要调优?

合理高效的使用两个关键硬件资源:CPU、内存。

JVM(Java Virtual Machine) Java虚拟机是指运行Java程序的虚拟系统,一般运行在linux、windows系统之上,使用有限的cpu,内存。

比如web应用在每次收到请求时,都会有一个线程去处理这个请求,这个过程至少会有业务对象被创建,这些对象会占用内存空间。

运行Java程序需要cpu的计算能力处理逻辑,也需要一定容量的内存存放Java对象和数据,但内存有限,需要回收整理不再使用的内存防止内存累计造成内存溢出(OutOfMemoryError);但是整理内存也是要调用CPU去做这个事情(垃圾回收),会影响web处理业务数据的速度,所以调整CPU处理业务和整理内存的时间占比会影响到1.程序处理业务的速度2.系统稳定性 这在极端(并发)情况下应该是比较重要的。

调优可以提高系统稳定性、业务处理速度

jvm调优主要依据

到这里只是讲了为什么要调优,没有讲怎么调优,调优可以理解为两点。

Java对象的生命周期

官方图片

官方图片

官方文档有图片显示,应用程序的对象的生命周期图,一般而言应用程序在启动的时候对象会有很多,然后呈现下降曲线,根据这个数据可以知道有些对象存活很久,有些对象在应用程序创建之后不久就无用了,需要回收清理掉,腾出内存空间给系统,提高内存使用效率。

不同的应用程序对象存活生命周期图会有所不同,所以堆的一些分代配置是可调式优化的。

内存管理

1.整理jvm的堆内存策略-垃圾回收,涉及到内存使用设计、分配,垃圾回收算法,垃圾回收器

如何找到垃圾(堆中不再需要的Java对象)、存活对象如何处理、内存怎么分配,什么垃圾回收器更适合应用。

堆分代设计

官方图片

堆分区

官方对堆的设计划分有讲到堆总的分为年轻代Young,老年代Old

Young又分为Eden(伊甸区),Survivor(幸存者区),逻辑上大多数创建的对象都存放在Eden区,经过垃圾回收存活的对象存放在Survivor区,多次在Survivor存活或者Survivor对象满了,会将Survivor区中的对象放入老年代Old

一般存活对象在堆区的转移: Young -> Survivor -> Old

吞吐量

2.吞吐量-CPU处理业务时间/CPU总时间(整理内存时间+处理业务时间)

CPU垃圾回收时间太小会出现什么问题?会不会回收对象的速度跟不上产生新对象的速度导致内存溢出。

CPU垃圾回收时间过大会出现什么问题?会不会应用系统处理业务出现卡顿,请求有延迟导致用户体验很差

官方指出的主要调优参数

垃圾收集器、堆和运行时编译器默认选择

这些是重要的垃圾收集器、堆大小和运行时编译器默认选择:

  • 垃圾优先 (G1) 收集器
  • 最大 GC 线程数受堆大小和可用 CPU 资源的限制
  • 初始堆大小为物理内存的 1/64
  • 最大堆大小为物理内存的 1/4
  • 分层编译器,同时使用 C1 和 C2

最大暂停时间目标 MaxGCPauseMillis

单次垃圾回收整理内存的最大时间

-XX:MaxGCPauseMillis=<nnn> 会让jvm在回收垃圾是,争取时间小于这个设置值(毫秒)。时间过小可能导致更频繁的触发垃圾回收。

吞吐量目标 GCTimeRatio

吞吐量目标是根据收集垃圾所花费的时间来衡量的,而在垃圾收集之外所花费的时间是应用程序时间

目标由命令行选项指定 -XX:GCTimeRatio=nnn,垃圾回收时间与应用时间之比为 1/ (1+nnn

-XX:GCTimeRatio=19 表示应用程序时间19, 垃圾花费时间1 ,所以垃圾回收时间占比1/(19+1),应用程序时间占比19/(19+1)。

GC日志 -verbose:gc / -Xlog:gc*

GC日志打印了垃圾回收的时间点,内存变化等详细信息,通过这个日志我们了解系统回收垃圾整理内存的具体比变化,是否吞吐量达标等,可以提取我们需要的信息,针对性调整jvm参数使系统更稳定或者提高吞吐量。

-verbose:gc ## 打印堆和垃圾信息
-XX:+PrintGCDetails  ## 附加信息
-XX:+PrintGCTimeStamps  ## 在每个集合的开始添加时间戳。这对于查看垃圾收集发生的频率很有用。

堆大小 -Xms -Xmx

-Xms=nnn 和 -Xmx=nnn 分别用于最小和最大堆大小。如果堆太小,对象过多,会频繁GC整理内存,需要调整堆的值,减少GC次数,提高吞吐量。

堆增长收缩 HeapFreeRatio

MinHeapFreeRatio 可用空间最小占比 默认值40

MaxHeapFreeRatio 可用空间最大占比 默认值70

使用这些参数,如果一个代中的可用空间百分比低于 40%,那么该代将被扩展以保持 40% 的可用空间,直到该代的最大允许大小。同样,如果空闲空间超过 70%,那么代将被收缩,只有 70% 的空间是空闲的,受限于代的最小大小。

年轻代 NewRatio

堆划分为年轻代和老年代,长期存活的Java对象会存入老年代。

-XX:NewRatio=3意味着年轻代和老年代的比例1:3 ,因此堆总大小分成4份,3/4内存是老年代,1/4内存是年轻代

幸存者空间大小 SurvivorRatio

年轻代划分有 eden(伊甸园)和survivor(幸存者) 两种类型 ,其中eden一个,survivor两个;

-XX:SurvivorRatio=6 表示将eden与survivor的比例设置为6/1,因为有两个survivor空间,所以一个survivor空间占年轻代大小的1/8

串行收集器 UseSeriaGC

-XX:+UseSeriaGC 表示使用串行垃圾收集器,它适合单核处理器机器

并行收集器 UseParallelGC

-XX:+UseParallelGC 并行执行次要收集,减少垃圾回收开销。它适用多处理器机器

主要并发收集器 UseConcMarkSweepGC UseG1GC

如果响应时间比总吞吐量更重要并且垃圾收集暂停必须保持短于大约 1 秒,则使用-XX:+UseConcMarkSweepGC或选择并发收集器-XX:+UseG1GC

并行垃圾收集器线程数 ParallelGCThreads

-XX:ParallelGCThreads=n 指定线程数量

posted @ 2021-09-27 19:33  楠予  阅读(120)  评论(0编辑  收藏  举报