您的位置:首页 > 其它

JVM关于GC一些见解

2016-07-08 19:38 267 查看
1.如果判断对象已经死亡:

     1)引用计数法:每个对象分配一个对象引用计数器,每当有个有一个引用指向该对象时,引用计数加1,当该引用不再指向该对象时,引用计数减1,当引用计数为0,可以认为该对象已经死亡。可以被GC回收。    

class ReferencedGC{
public Object obj=null;
}
public class Test{
public static void main(){
Reference ra=new Reference();
Reference rb=new Reference();
ra.obj=rb;
rb.obj=ra;
}
}
从代码中可以看到ra rb是无论如何引用计数不为0,但是根据运行结果看到,JVM还是把这两个对象回收了,这也说明JVM并不是通过引用计数法进行判断对象是否死亡。

    2)可达性算法:主流的虚拟机都是通过可达性分析进行判断对象是否已经死亡。基本思想是是从一系列被称为"GC Roots"为起点进行向下搜索,这个搜索路径被称为"引用链",当一个对象到GC Roots没有一条引用链,对象是不可用的,可以被GC回收。



从图中可以看到object 5,6,7与GC Roots 之间是不可达的,也就是说其被判定是可回收的对象,等待被GC回收。

2.JVM垃圾回收算法:

   1)标记-清除方法:JVM将要被回收的对象进行标记,然后开始回收对象。但是这有缺陷就是:1.效率不高2.由于内存中对象的地址是不连续的回收的对象造成大量的内存的碎片,因此如果有较大的内存的对象需要被开辟时候,不得不再一次进行垃圾回收算法。

   


   2)复制算法:将内存分成等大的两块,每次只是用其中的一块,当一块的内存即将使用完毕时候,将存活对象的拷贝到另一块的内存中,同时可回收的对象进行回收,并调整堆顶指针,使得存活对象连成一块连续的内存。每次都是对内存的半区进行回收,并且内存分配时不会造成内存碎片的情况,但是有缺陷就是可用内存减少一半,效率降低。



   3)标记-整理方法:复制算法会造成50%的内存不可被使用,资源的浪费,因此人们在标记-清除的算法的基础进行改进出现了标记-整理的算法,这个进行垃圾回收时候,存活对象向前移动,使所有的存活对象连续,而从存活对象的端末开始进行垃圾回收,这样同时使得回收的内存空间形成一块连续的内存。

    


  4)分代算法:将JAVA堆分成老年代,新生代。新生代每次垃圾回收都会有大量的对象死亡,只有少量的对象的存活,可以使用"复制"算法。而老年代的存活率高,没有额外的内存空间进行担保,因此可以使用"标记-整理"或者"标记-清除"算法。   

     
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jvm 垃圾回收