jvm之垃圾收集器

判断对象是否死亡的方法:

  (1)引用计数法:若对象存在引用,那么该对象的引用计数器加1,若该对象的引用计数器为0表示没有被引用,则被回收

  (2)可达性分析算法:判断该对象跟gc root之间有没有关联,若没有关联那么被回收。

可以作为gc roots的对象:

(1)虚拟机栈中的引用对象

(2)方法区中类的静态属性所引用的对象

(3)方法区中常量所引用的对象

引用:

强引用:直接关联着的对象,eg:A a = new A();

软引用:在发生内存溢出之前会将软引用的对象清除掉,若还是内存不够实用,那么抛出异常

弱引用:不论内存是否足够,都会回收的对象

虚引用:不会对内存造成影响。

垃圾收集算法:

(1)标记清除算法

            缺点:容易造成大量的空间碎片,提前触发gc

(2)复制算法:

        优点:不会造成空间碎片

(3)标记整理算法:

        整合上述两者算法的优缺点而产生的。

(4)分代垃圾收集算法

gc roots实现原理:

        可达性分析时,需要确保对象之间的引用关系的正确,否则会造成严重的后果,因此 可达性分析时就需要将所有的用户线程停止下来,来判断是否可达。

        jvm借助oopmap来保存对象之间的引用关系,但是众多的oopmap会造成空间上的消耗,因此出现了安全点。

        安全点中记录了所有的引用关系,因此可以在安全点上来进行可达性分析。

                安全点策略:抢占式中断   主动中断。

                    抢占式中断 : 发生可达性分析时,停止所有的线程,若有线程停止的地方不在安全点上,那么恢复线程,在安全点上停止

                    主动中断 : gc在安全点上设置可达性分析的标志,用户线程轮询该标志,来停止线程。(主要使用的方式

        安全区:在安全区进行可达性分析,是安全的,解决了由于用户线程挂起而不能到达安全点的问题。




垃圾收集器:

(1)serial收集器:用于新生代,单线程,使用复制算法

(2)parnew收集器:新生代,多线程,复制算法

(3)parallel Scavenge收集器:新生代,多线程,复制算法,目标提高用户的吞吐量。

降低gc时间:通过减少新生代的大小来实现,导致频繁gc,降低吞吐量

(4)serial Old收集器:serial收集器的老年代版本,标记-整理算法,单线程

(5)parallel Old收集齐:parallel Scavenge收集器的 老年代版本,多线程,标记-整理算法

(6)cms: 多线程,并发,标记清除算法,老年代。

gc过程:初始标记(标记gc roots的关联关系) ---》  并发标记(用户线程边执行,边标记) ----》 最终标记(标记并发标记过程中gc roots发生变化的节点) ---》并发清理

缺点:占用部分cpu导致吞吐量降低。 无法清除浮动垃圾(并发标记时产生)。使用了标记-清除算法导致空间碎片

(7)G1:并行,并发,分代收集,空间整合(整体采用标记-整理算法,局部使用复制算法),可预测的停顿(后台维护一张优先列表,根据回收时间来对region区域进行回收),老年代。

gc过程跟cms相同。

如何避免全堆扫描:jvm使用remember set来记录分代对象之间的关联关系,来避免全堆扫描。

你可能感兴趣的:(jvm)