垃圾回收机制

2019-03-13  本文已影响0人  蜡笔没了小新_e8c0

垃圾回收的时间?

当Eden区没有足够空间进行分配时,会触发Minor GC;
升级到老年代所需的内存大于老年代剩余内存就会触发Full GC。

如何判断一个对象是否应该回收:

该算法的缺点很难解决对象之间相互循环引用的问题。

可以作为GC Root的对象
1.虚拟机栈中引用的对象(栈帧中的本地变量表)
2.方法区中的常量引用的对象
3.方法区中的类静态属性引用的对象
4.本地方法栈中JNI(Native方法)的引用对象
5.活跃线程的引用对象

垃圾收集算法:

主要不足:一个是效率问题,标记和清除两个过程的效率都不高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行会过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

该算法将内存缩小到原来的一半所需代价太高。

分代收集算法

年轻代(标记-复制)

对象如何晋升到老年代

  • 经历一定Minor次数依然存活的对象(默认为15)
  • Survivor区中存放不下的对象
  • 新生成的大对象(-XX:+PretenuerSizeThreshold)

常用的调优参数

垃圾收集器

HotSpot虚拟机的垃圾收集器

1.初始标记
2.并发标记
3.重新标记
4.并发清除
其中,初始标记和重新标记这两个步骤仍然需要“Stop The World”。初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,并发标记阶段就是进行GC Roots Tracing的过程,而重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。

具有以下特点:
1.并行与并发
2.分代收集
3.空间整合
4.可预测的停顿

在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域。虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。

G1收集器运作大致可划分为以下几个步骤:
1.初始标记
2.并发标记
3.最终标记
4.筛选回收
初始标记阶段仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运行时,能在正确可用的Region中创建对象,这阶段耗时较长,但可与用户程序并发执行。但最终标记阶段则是为了修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程Remembered Set Logs里面,最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set中,这阶段需要停顿线程,但是可并行执行。最后在筛选回收阶段首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。

上一篇 下一篇

猜你喜欢

热点阅读