Java中的GC回收机制

为什么要进行GC回收?

当我们新建一个对象时,系统就会为其分配一定的内存空间,而有时候新建的对象没有去使用时,不回收的话会极大浪费内存空间,造成系统效率低下

什么时候进行GC回收?

1、当CPU空闲的时候

2、执行System.gc()方法的时候

3、堆内存满了以后

GC的算法有引用计数法和可达性分析的算法进行回收

引用计数法:当新建对象就创建一个与之对应的计数器,当对象被使用时计数器就加一,而当不执行此对象时计数器就减一,最终计数器为0的对象将会被回收。

优点:执行速度快

缺点:当存在相互引用时会造成内存泄漏

相互引用

public class test{
       public static void main(String []args){
              public Object instance=null;
              test test1 = new test();
              test test2 = new test();
              test1.instance = test2;
              test.instance = test1;
    }  
}

  内存泄漏:内存泄漏是指无用对象(不再引用对象)持续占有内存,得不到及时的释放,从而造成的内存空间的浪费。

可达性分析法:

通过一系列名为"GC Roots"的对象作为起点,从这些节点往下搜寻,搜索所经过的路径称为引用链,当某个对象没有任何引用链相连时,证明此对象无用,回收。

如何回收?

回收算法有四种:标记清除法、复制算法、标记整理法、分代回收法

标记清除法:

对内存中无用的对象进行标记,然后回收,缺点是会造成内存不连续,空间的浪费。

复制算法:

将内存分成两块,每次只使用其中的一块,当这一块使用完之后就将这一块中存活的对象复制到另一块内存中,已经使用完的内存空间清除。缺点是将内存缩成原来的一半。对于存活较多的对象,要进行复制,效率较低。

标记整理法:

与标记清除法有一定的类似,不过标记整理法仅对存活的对象进行处理,对不调用的对象不进行处理,将活的对象复制到另一半内存中并整理,不会产生内存碎片。

分代回收法:

1、年轻代:分为三个区,Eden和两个活区(survivor0和survivor1)分别占80%、10%、10%。

将Eden中和survivor中存活的对象拷贝到另一个survivor中(使用的是stop-and-copy的方法),当Eden满了以后执行minorGC,并将剩余存活的对象放到survivor0中,回收Eden中没有存活的对象。当survivor0满了以后,就将存活的对象复制到survivor1中,不存活的对象回收。依次去存。

2、老年代:(存放较大的实例化对象和在新生代中存活很久的对象)

使用的是标记整理算法,即标记存活对象,向一端移动,保证内存完整性,然后将未标记的清理掉。当老年代不够用,也会执行majorGC,FullGC.

猜你喜欢

转载自www.cnblogs.com/hjdk05/p/11923753.html