jvm之内存分配策略

GC日志的基本格式,如下是一次GC的日志:

本地环境是JDK1.8

[GC (Allocation Failure) [PSYoungGen: 2536K->488K(2560K)] 5501K->5511K(9728K), 0.0058699 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] 
[Full GC (Ergonomics) [PSYoungGen: 488K->0K(2560K)] [ParOldGen: 5023K->4855K(7168K)] 5511K->4855K(9728K), [Metaspace: 3483K->3483K(1056768K)], 0.0658519 secs] [Times: user=0.11 sys=0.00, real=0.06 secs] 
[GC (Allocation Failure) [PSYoungGen: 2048K->512K(2560K)] 6903K->6877K(9728K), 0.0037400 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
首先开头的[GC和[Full GC表示了这一次GC的类型,如果有full,表示发生了stop the world。
 
 

[]内部的数据a->b(c),a表示GC前该区域占用内存大小,b表示GC后该区域占用内存大小,c表示该区域的总内存大小。

[]外部的数据a->b(c),a表示GC前堆使用内存大小,b表示GC后堆占用内存大小,c表示该堆的总内存大小。

后面的事件分别表示用户态消耗的CPU时间、内核态消耗的CPU时间和操作从开始到结束经过的墙钟时间。

CPU时间与内核时间区别是,内核时间包含非运算耗时,线程阻塞、I/O等。如果是多CPU,CPU时间会累加这些CPU时间,所以user时间有可能比real时间大。

垃圾回收相关的参数设置:

UseSerialGC:虚拟机运行在Client模式下时默认值,使用Serial+Serial Old收集器组合

Client模式和Server模式:Server模式启动慢,但是运行后会进行优化。默认情况下虚拟机会判断服务器,如果CPU数量大于2,内存大于2G会以server模式启动。默认情况下Client模式-Xms1m,-Xmx10m;Server模式-Xms128m,-Xmx1024m。

UseParNewGC:使用ParNew+Serial Old收集器组合

扫描二维码关注公众号,回复: 10971578 查看本文章

UseConcMarkSweepGC:使用ParNew+GMS+Serial Old组合

useParallelGC:Server模式的默认值,使用Parallel Scavenge+Serial Old组合

UseParallelOldGC:使用Parallel Scavenge+Parallel Old组合
SurvivorRatio:默认8,eden与survivor区域比例
PreTenureSizeThreshold:直接晋升到老年代的对象大小
MaxTenuringThreshold:晋升到老年代的年龄
UseAdaptiveSizePolicy:动态调整堆大小,晋升老年代年龄
HandlePromotionFailure:是否允许分配担保,jdk1.6之后不再起作用,都会进行担保
ParallelGCThreads:GC是的回收线程数
GCTimeRatio:GC占总时间比,默认99,即允许1%GC时间,只有Parallel Scavenge收集器有效
MaxGCPauseMillis:GC最大停顿时间,只有Parallel Scavenge收集器有效
CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少时后触发GC,默认68%
UseCMSCompactAtFullCollection:设置CMS收集器完成垃圾回收后是否要进行一次内存碎片整理
CMSFullGCsBeforeCompaction:CMS收集器在进行多少次GC后进行一次内存碎片整理

 

内存分配策略:

一般情况下,对象分配到Eden区。当Eden中没有足够空间时,进行一次Minor GC。

Minor GC:新生代GC

Major GC/Full GC:老年代GC

大对象会直接进入老年代,大对象只需要大量连续空间的对象,-XX:PreTenureSizeThreshold用来控制大对象的大小,大于这个值的对象直接分配到老年代。

长期存活的对象进入老年代,对象出生在Eden区没经过一次Minor GC后仍然存活,并且被Survivor容纳,则年龄加1。当年龄到达一定程度,默认15,晋升到老年代,通过-XX:MaxTenuringThreshold设置。

动态年龄判断:虚拟机为了更好的适应不同程序的内存状况,虚拟机并不会永远要求到达-XX:MaxTenuringThreshold设置的年龄才进升,如果Survivor空间中相同年龄的所有对象大小大于Survivor空间的一半,年龄大于或等于该年龄的对象直接进入老年代。

空间分配担保:因为新生代采用复制算法,如果一次GC后所有对象都存活,那就需要老年代进行担保,把Survivor无法容纳的对象直接进入老年代。所以在进行Minor GC时,会先检查老年代最大连续可用空间是否大于新生代所有对象的总空间,如果成立,则Minor GC是安全的。如果不是,则会检查老年代的最大连续可用空间是否大于历次晋升到老年代对象的平均大小,如果大小,则进行一次Minor GC,尽管有风险。如果小于,进行Full GC。

发布了45 篇原创文章 · 获赞 21 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/ly262173911/article/details/78524550