java GC垃圾回收策略
1.首先我们来了解GC是什么
GC是一种垃圾回收机制,为什么说GC是垃圾回收机制呢?就那C#来对比吧,在C#中当你创建一个对象但是这个对象用到了一半没有用了这个时候必须要手动回收对象,不然的话这样的对象越来越多的话,就会形成内存泄漏,而在java中有GC回收机制,简单的来说就是GC可以自动回收没有用的对象,但是GC不会总是存在GC会隔一会时间来一次,GC会根据自己给内存来调整清理的大小。
2.GC怎么找到垃圾
引用计数法:
原理是:此对象有一个引用,则+1;删除一个引用,则-1。只用收集计数为0的对象。缺点是: (1)无法处理循环引用的问题。如:对象A和B分别有字段b、a,令A.b=B和B.a=A,除此之外这2个对象再无任何引用,那实际上这2个对象已经不可能再被访问,但是引用计数算法却无法回收他们。(2)引用计数的方法需要编译器的配合,编译器需要为此对象生成额外的代码。如赋值函数将此对象赋值给一个引用时,需要增加此对象的引用计数。还有就是,当一个引用变量的生命周期结束时,需要更新此对象的引用计数器。引用计数的方法由于存在显著的缺点,实际上并未被JVM所使用。
根计算法:
我们先来看一个图
原理是:根计算法就很好的解决了引用计数法的缺陷,如上图对象在堆中,在图中1,2,4,6对象就不会被GC认为是垃圾,为什么6对象不是垃圾因为,对象4调用了对象6而对象4正在被本地方法栈引用,从这个地方就可以看出来了6对象是有根的所以对象6不是垃圾,而对象3,5的话他们两个在相互引用这个情况就是引用计数法的缺陷,但是3,5对象没有根所以就被GC认为这个两个对象是垃圾。
3.GC怎么回收垃圾
标记清除:这种简单,但是缺点是有内存碎片效率比较低
分段复制法:复制算法将内存划分为两个区间,在任意时间点,所有动态分配的对象都只能分配在其中一个区间(称为活动区间),而另外一个区间(称为空闲区间)则是空闲的,当有效内存空间耗尽时,JVM将暂停程序运行,开启复制算法GC线程。
标记整理算法:
标记:它的第一个阶段与标记/清除算法是一模一样的,均是遍历GC Roots,然后将存活的对象标记。
整理:移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。因此,第二阶段才称为整理阶段。
分代收集:分为新生区 生存区 老年区 永久区