JVM垃圾收集器与内存分配策略(3)

-XX:+UseAdaptiveSizePolicy: 这是一个开关参数, 打开这个参数后, 不需要手工指定新生代大小,Eden和Survior区的比例,晋升老年代对象年龄等细节参数。 虚拟机会根据当前系统的运行情况动态调整这些参数以提供最合适的停顿时间或者最大吞吐量。

与ParNew收集器的区别:可以设置吞吐量和最大停顿时间; 具有自适应调节策略。

4,Serial Old收集器:

描述:Serial Old是Serial收集器的老年代版本, 单线程收集器, 使用“标记-整理”算法。

5,Parallel Old收��器:

描述: Parallel Scavenge收集器的老年代版本;吞吐量优先的收集器

6,CMS收集器: Concurrent Mark Sweep

描述:以获取最短回收停顿时间为目标;基于“标记-清除”算法

步骤:

初始标记:标记GC Roots能直接关联到的对象, 速度很快; 该阶段需要stop the world

并发标记:进行GC Roots trace, 并发进行

重新标记:修正并发期间因为用户程序继续运行而导致变动的那一部分对象的标记记录。

并发清除:

缺点:

CMS收集器对CPU资源非常敏感, 它虽然不会导致用户线程停顿, 但是由于占用了一部分cpu时间而导致应用变慢, 总吞吐量会降低。

CMS收集器无法处理浮动垃圾, 可能出现Concurrent Mode Failure失败, 导致另一次full gc的产生。并发清理过程中, 用户线程生成的垃圾不能被本次回收所清理, 只能等到下次GC时清理, 这部分垃圾称为“浮动垃圾”; 每次垃圾清理时, 都要为用户线程的运行留出内存空间, 所以不能等到没有空间时才回收。如果CMS运行期间预留的内存空间无法满足程序需要, 就会出出现一次“Concurrent Mode Failure”失败, 这时虚拟机将启动后背预案:临时使用Serial Old收集器重新进行老年代的垃圾收集; 使用-XX:CMSInitiatingOccupancyFraction设置阈值

CMS是基于“标记-清理”算法实现的收集器, 意味着收集结束时会产生大量的空间碎片。 空间碎片过多时, 会因为无法找到足够连续的内存而无法为大对象分配内存, 造成FULL GC

八、 理解GC日志

1.停顿类型:

[GC : minor GC, [Full GC: full GC

2. GC的位置:

[DefNew:Default New Generation      Serial收集器新生代

[ParNew:  Parallel 新生代

[PSYoungGen: Parallel Scanvenge收集器的新生代

[Tenured:  老年代

[Perm:  永久代

3.回收前后内存空间变化:

35592K -> 1814K(36288K): 回收前内存空间大小 -> 回收后内存空间大小(总的内存空间大小

九、内存分配与回收策略:

大的方向说, 对象主要分配在堆的新生代的Eden区上,如果启动了本地线程分配缓冲, 将按线程优先在TLAB上分配。

1.对象优先在Eden上分配:

当Eden上没有足够的空间分配时, 虚拟机会发起一次Minor GC, 将Eden上和一个survivior上存活的对象复制到另外一个Survivor空间上, 如果另外一个Survivior空间上没有足够的空间, 将会将存活的对象直接移动到老年代, 如果老年代也没有足够的空间, 虚拟机将会发起一次Full GC, 如果Full GC之后还是放不下, 则会报OOM异常。

2.大对象会直接进入老年代:

虚拟机提供一个参数, -XX:PretenureSizeThreshould, 大于这个值的对象直接在老年代分配, 避免Eden区域Survivior区的来回复制。

3.长期存活的对象直接进入老年代:

虚拟机每个对象定义了一个对象年龄计算器, 每经过一次Minor GC, 对象年龄加一, 当对象年龄达到一定数时(默认15),将会晋升到老年代。 阈值设置参数:-XX:MaxTenurngThreshould

4.动态对象年龄判断:

如果Survivior空间中相同年龄的对象的大小总和大于survivior空间的一半时, 大于等于该年龄的对象就可以直接进入老年代。

5.空间分配担保:

准备Minor GC时, 虚拟机首先会检查老年代的剩余空间是否大于新生代所有对象的总空间, 如果大于, 则可以进行Minor GC; 否则, 会去查看是否允许担保失败(HandlePromotionFailure), 如果不允许,虚拟机会直接发起一次Full GC; 如果允许, 虚拟机会去检查老年代剩余空间是否大于历次晋升到老年代对象的平均大小, 如果不大于, 则会发起一次Full GC; 如果大于, 则会发起Minor GC, 如果这时发现, 老年代没有足够空间来容纳新生代晋升来的对象的总大小, 这时仍要触发一次Full GC, 这个圈子绕的就有点大了。

十、Full GC 和Minor GC:

Minor GC: 发生在新生代, 速度比较快

Full GC: 发生在老年代, 一般都伴随这一次Minor GC

Minor GC一般都要比Minor GC慢十倍以上,因为新生代采用复制算法, 速度比较快; 而老年代一般采用标记-清理/整理算法;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f69341f4702a42ee614df0d8f973eea9.html