java年轻代和年老代默认比值,jvm调优

1,jvm常用参数

可以通过java -XX:+PrintFlagsFinal命令查看jvm各参数在当前机器上的默认值,

或者jinfo -flag MetaspaceSize pid查看指定进程的参数的值:

参数

功能

默认值

-Xms

初始堆大小

物理内存1/64

-Xmx

最大堆大小

物理内存1/4

-Xmn

年轻代大小

(NewSize与MaxNewSize设为一致)

堆的1/3

-XX:MetaspaceSize

元数据区大小

20.8M

-XX:MaxMetaspaceSize

元数据区最大值

4g

-XX:NewSize

年轻代默认大小

2m

-XX:MaxNewSize

年轻代最大值(根据 NewRatio计算)

-Xss

每个线程的堆栈大小

1M

-XX:NewRatio

新生代和老年代比值

2

-XX:SurvivorRatio

Eden与Survivor的占用比例。

默认值8表示survivor占用2/8(两个survivor),Eden占用6/8。

8

-XX:+AggressiveOpts

启用JVM开发团队最新的调优成果。

例如编译优化,偏向锁,并行年老代收集等。

默认不启用

--XX:MaxHeapFreeRatio

空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。

70

--XX:MinHeapFreeRatio

空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制。

40

-XX:-DisableExplicitGC

禁止在运行期显式地调用 System.gc()。

开启该选项后,GC的触发时机将由Garbage Collector全权掌控。

默认不启用

-XX:-UseConcMarkSweepGC

启用CMS低停顿垃圾收集器

默认不启用

-XX:+UseParNewGC

新生代并行回收

默认不启用

-XX:+ScavengeBeforeFullGC

在Full GC前触发一次Minor GC

默认启用

-XX:ParallelGCThreads

并行收集器线程数

如果cpu线程数<=8则使用cpu线程数,否则增加5/8的线程总数

-XX:ConcGCThreads

并发垃圾收集器使用的线程数量

XX:ParallelGCThreads/4

-XX:+UseG1GC

使用g1回收器

默认不启用

-XX:MaxGCPauseMillis

最大GC停顿时间,这是个软目标,JVM将尽可能(但不保证)停顿小于这个时间

200ms

-XX:InitiatingHeapOccupancyPercent

启动并发GC周期时的堆内存占用百分比

45

-XX:G1ReservePercent

设置堆内存保留为假天花板的总量,以降低提升失败的可能性

10

-XX:G1HeapRegionSize

使用G1时Java堆会被分为大小统一的的区(region)。此参数可以指定每个heap区的大小. 默认值将根据 heap size 算出最优解. 最小值为 1Mb, 最大值为 32Mb.

-XX:+CMSScavengeBeforeRemark

在CMS GC前启动一次ygc,目的在于减少old gen对ygc gen的引用,降低remark时的开销-----一般CMS的GC耗时 80%都在remark阶段

默认不启用

-XX:CMSInitiatingOccupancyFraction

堆内存使用达到70%时启动cms gc

70

-XX:+UseCMSInitiatingOccupancyOnly

只是用设定的回收阈值(XX:CMSInitiatingOccupancyFraction),如果不指定,JVM仅在第一次使用设定值,后续则自动调整

默认不启用

XX:+AlwaysPreTouch

当JVM初始化时预先对Java堆进行预先摸底(Pre-touch),堆的每个页初始化时满足需求,而不是应用执行时递增。

默认不启用

2,jvm调优(g1)

由于java后续版本g1是主流,所以调优针对的是g1。

2.1,堆的大小上限一般不要超过32gb

在堆中,32位的对象引用占4个字节,而64位的对象引用占8个字节。也就是说,64位的对象引用大小是32位的2倍。java6之后支持-XX:+UseCompressedOops开启指针压缩,默认开启。

Enables the use of compressed pointers (object references represented as 32 bit offsets instead of 64-bit pointers) for optimized 64-bit performance with Java heap sizes less than 32gb.

指针压缩原理:

​32位内最多可以表示4GB,64位地址分为堆的基地址+偏移量,当堆内存<32GB时候,在压缩过程中,把偏移量/8后保存到32位地址。在解压时再把32位地址放大8倍,所以启用CompressedOops的条件是堆内存要在4GB*8=32GB以内。

​如果GC堆大小在4G以上32G以下,则启用UseCompressedOop ,如果GC堆大小大于32G,压指失效,使用原来的64位。

所以正常情况下,堆内存最大不要超过32gb。

2.2,使用g1的时候不能设置年轻代的大小(-Xmn)

在使用g1回收器的时候如果同时设置了-Xmn参数,也就是指定了年轻代的大小,那么这将影响g1的回收,因为一旦设置了年轻代的大小,那么g1将无法动态调整堆的各区间的大小,同时g1的最大暂停时间目标将不再起作用。与此同时,最大暂停时间(-XX:MaxGCPauseMillis)只是个期望值,g1无法绝对保证,而且设置最大暂停时间的值不能用平均响应时间来设置,应该用上限响应时间或者接近上限响应时间的值来设置。

2.3,解决回收过程中的转移失败(Evacuation Failure)

​ gc日志中常可以看到"evacuation failure", "to-space exhausted", "to-space overflow", "promotion failure"之类的输出,这是由于g1在回收的过程中无法找到空闲空间放置存活对象,这种情况称为Evacuation Failure(类比cms中的晋升失败):

924.897: [GC pause (G1 Evacuation Pause) (mixed) (to-space exhausted), 0.1957310 secs]

924.897:[GC pause (G1 Evacuation Pause) (mixed) (to-space overflow), 0.1957310 secs]

​ 这个易导致full gc,而g1中的full gc是Serial收集器,这会导致秒级的暂停时间,所以在g1中要尽量避免出现full gc。针对此情况可以做一下调整:

减少InitiatingHeapOccupancyPercent参数的值(默认45)提前启动标记周期,但同时也会增加GC发生频率;

增加ConcGCThreads参数的值来增加并发标记的线程数目,提高gc的效率,但同时也会占用更多工作线程的资源;

增加 -XX:G1ReservePercent参数的值(并相应增加总的堆大小),为"目标空间"(to-space)增加预留内存量。

2.4,巨型对象分配(Humongous Allocation)

​ 对于 G1 GC,任何超过区域(G1HeapRegionSize)一半大小的对象都被视为“巨型对象”。此类对象直接被分配到老年代中的“巨型区域”。这些巨型区域是一个连续的区域集。StartsHumongous 标记该连续集的开始,ContinuesHumongous 标记它的延续。

​ g1只会在标记周期结束的时候清理巨型对象,或者在full gc的时候其不可达。巨型对象不会移动,即使是full gc时也是如此,这会过早的减慢full gc的效率。

由于每个 StartsHumongous 和 ContinuesHumongous 区域集只包含一个巨型对象,所以没有使用巨型对象的终点与上个区域的终点之间的空间(即巨型对象所跨的空间)。如果对象只是略大于堆区域大小的倍数,则此类未使用的空间可能会导致堆碎片化。

巨型对象分配日志示例:

280.008: [G1Ergonomics (Concurrent Cycles) request concurrent cycle initiation, reason: occupancy higher than threshold, occupancy: 62344134656 bytes, allocation request: 46137368 bytes, threshold: 42520176225 bytes (45.00 %), source: concurrent humongous allocation]

如果巨型分配导致连续的并发周期,并且此类分配导致老年代碎片化,可以增加 -XX:G1HeapRegionSize,这样一来,之前的巨型对象就不再是巨型对象了,而是采用常规的分配路径,或者分析程序本身以减少此类对象的产生。-XX:G1HeapRegionSize,其值为2的次幂,最小值为 1mb, 最大值为 32mb。

2.5,垃圾回收算法CMS和G1的选择

程序调优的两个目标特点:

指标

定义

响应能力

响应能力又或者延时(Latency)指系统对任务的响应速度,比如有人机交互的系统(gui程序,web界面)。响应能力优先的系统,对系统长时间的卡顿是无法接受的。

吞吐量

吞吐量(Throughput)指系统单位时间内处理任务的能力,吞吐量优先的系统,更需要考虑的是系统处理大量任务的效率,至于单次任务的效率无足轻重,所以卡顿是可以接受的,只要整体效率有保障。

响应能力和吞吐量是衡量系统性能的两个重要指标,这两个指标并不是绝对对立的,最终系统的表现取决于系统的瓶颈。

类别

优点

缺点

适用场景

CMS

并发收集、低停顿

对cpu资源敏感;

无法处理浮动垃圾;

容易出现内存空间碎片;

对响应时间敏感,cpu资源丰富,

追求服务的响应速度,

相应牺牲服务的吞吐量。

G1

无内存空间碎片的问题;

可预测的停顿;

配置少,可动态调优至最优配置

g1触发full gc时会退化使用Serial收集器进行回收,导致秒级的暂停时间

面向服务端,适用于多核,大内存的服务端系统。

实现高吞吐量的同时,尽可能满足gc暂停时间的要求

2.6 jvm参数示例

### g1

-server

-Xms10g

-Xmx10g

-XX:+AlwaysPreTouch

-XX:+UseG1GC

-XX:+ScavengeBeforeFullGC

-XX:+DisableExplicitGC

### cms

-server

-Xms10g

-Xmx10g

-XX:+AlwaysPreTouch

-XX:+UseParNewGC

-XX:+UseConcMarkSweepGC

-XX:+CMSClassUnloadingEnabled

-XX:+CMSPermGenSweepingEnabled

-XX:+ScavengeBeforeFullGC

-XX:+CMSScavengeBeforeRemark

-XX:+DisableExplicitGC

3,jvm 日志

3.1 gc日志参数

参数

功能

-verbose:gc

输出一些详细的gc信息(等同 -XX:+PrintGC),

-XX:+PrintGC后续版本弃用

-XX:+PrintGCDetails

输出gc的详细信息

-XX:+PrintGCTimeStamps

输出GC的时间戳(以基准时间的形式)

-XX:+PrintGCDateStamps

输出GC的时间戳(以日期的形式)

-XX:+PrintAdaptiveSizePolicy

打印自适应收集的大小,默认关闭

-XX:+UseGCLogFileRotation

打开或关闭GC日志滚动记录功能,要求必须设置 -Xloggc参数,并且开启后默认的文件数和文件大小不受限制

-XX:NumberOfGCLogFiles

设置滚动日志文件的个数,必须大于1

-XX:GCLogFileSize

设置滚动日志文件的大小,默认8k

-Xloggc:[file]

将gc信息输出到单独的日志文件,示例: Xloggc:/path/to/gc/logs/log.txt

3.2 gc日志解读

cms日志示例:

[GC [ParNew: 471013K->44702K(471872K), 0.0151339 secs] 1092059K->673523K(2044736K), 0.0154045 secs] [Times: user=0.18 sys=0.04, real=0.02 secs]

[Full GC [PSYoungGen: 1403K->33K(912504K)] [ParOldGen: 8K->1261K(1048576K)] 1411K->1261K(1926080K), [Metaspace: 3508K->3508K(1056768K)], 0.0083870 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

各个指标对应的含义:

[GC类型(导致原因) [发生区域: gc前大小->gc后大小(总大小), gc占用时间] gc前堆大小->gc后堆大小(堆总大小), 该内存区gc占用时间] [Times: 用户态耗时, 内核态耗时, 实际耗时(wall clock time)]

注意:Minor GC,Major GC均会导致STW

G1日志示例

0.522: [GC pause (young), 0.15877971 secs]

​ 这是一个转移暂停,距离进程启动的0.522秒开始,所有被转移的是年轻代分区,一共花费了0.15877971秒。

​ 转移暂停也可以是混合的,比如:1.730:[GC pause (mixed), 0.32714353 secs],此时分区包含所有的年轻代分区和部分老年代分区。

[Parallel Time: 157.1 ms]

并行GC Worker线程的总耗时,下面缩进部分是worker线程的子任务

[GC Worker Start (ms): 522.1 522.2 522.2 522.2

每个worker线程的启动时间(距离jvm启动的时间)

Avg: 522.2, Min: 522.1, Max: 522.2, Diff: 0.1]

所有线程启动时间的avg,min,max,diff(下同,不赘述)

[Ext Root Scanning (ms): 1.6 1.5 1.6 1.9

每个线程扫描Roots(全局变量,寄存器,线程栈,vm数据结构)的时间

Avg: 1.7, Min: 1.5, Max: 1.9, Diff: 0.4] 同上

[Update RS (ms): 38.7 38.8 50.6 37.3

每个线程更新Remember Set(RSet)时间,RSet保存引用

Avg: 41.3, Min: 37.3, Max: 50.6, Diff: 13.3]

[Processed Buffers : 2 2 3 2

Sum: 9, Avg: 2, Min: 2, Max: 3, Diff: 1]

[Scan RS (ms): 9.9 9.7 0.0 9.7

扫描RSet的时间,每个分区的RSet包含指向分区的Card。这个阶段扫描CSet集合中所有指向分区的Card。

Avg: 7.3, Min: 0.0, Max: 9.9, Diff: 9.9]

[Object Copy (ms): 106.7 106.8 104.6 107.9

拷贝CSet集合里面所有分区存活对象到另一个分区的时间。

Avg: 106.5, Min: 104.6, Max: 107.9, Diff: 3.3]

[Termination (ms): 0.0 0.0 0.0 0.0

Avg: 0.0, Min: 0.0, Max: 0.0, Diff: 0.0]

[Termination Attempts : 1 4 4 6

Sum: 15, Avg: 3, Min: 1, Max: 6, Diff: 5]

[GC Worker End (ms): 679.1 679.1 679.1 679.1

每个线程的停止时间

Avg: 679.1, Min: 679.1, Max: 679.1, Diff: 0.1]

[GC Worker (ms): 156.9 157.0 156.9 156.9

每个线程的耗时

Avg: 156.9, Min: 156.9, Max: 157.0, Diff: 0.1]

[GC Worker Other (ms): 0.3 0.3 0.3 0.3

每个线程执行除了上面操作的其他任务的耗时

Avg: 0.3, Min: 0.3, Max: 0.3, Diff: 0.0]

[Clear CT: 0.1 ms]

串行清除Card Table的时间

[Other: 1.5 ms]

[Choose CSet: 0.0 ms] 为CSet选择Region的时间

[Ref Proc: 0.3 ms] 处理对象引用的时间

[Ref Enq: 0.0 ms] 引用入ReferenceQueues队列的时间

[Free CSet: 0.3 ms] 释放CSet时间

[Eden: 12M(12M)->0B(10M) Survivors: 0B->2048K Heap: 13M(64M)->9739K(64M)]

Eden在回收之前容量和占用都是12MB,回收之后占用为0,容量为13MB(有新的分区加入Eden)。

Survivor回收之后,占用从0变到2048KB,整个堆在回收之前占用和容量是14MB和64MB,回收之后是9739KB和64MB。

[Times: user=0.59 sys=0.02, real=0.16 secs]

## 3.3 gc日志可视化

可以使用`gcviewer`对gc日志进行可视化,这样可以更直观的观察和分析gc日志,其地址为:

[https://github.com/chewiebug/GCViewer](https://github.com/chewiebug/GCViewer)

参考链接:

[https://blog.csdn.net/Dax1n/article/details/77163540](https://blog.csdn.net/Dax1n/article/details/77163540)

https://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

[https://juejin.im/post/5c4c8ad9f265da6179752b03](https://juejin.im/post/5c4c8ad9f265da6179752b03)

[https://www.cnblogs.com/happyflyingpig/p/8918675.html](https://www.cnblogs.com/happyflyingpig/p/8918675.html)

[https://segmentfault.com/a/1190000007815623](https://segmentfault.com/a/1190000007815623)

[https://blog.51cto.com/14237164/2379588](https://blog.51cto.com/14237164/2379588)

[https://www.oracle.com/technetwork/cn/articles/java/g1gc-1984535-zhs.html](https://www.oracle.com/technetwork/cn/articles/java/g1gc-1984535-zhs.html)

[http://www.raincent.com/content-85-4354-5.html](http://www.raincent.com/content-85-4354-5.html)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值