引用计数算法
给对象中添加一个引用计数器,每当有一个地方引用它时,+1;当引用失效时,-1。任何时刻计数器为0的对象不能再被使用。
问题:对象之间相互循环引用的问题
public class ReferenceCountGC{
public object instance = null;
public static void testGC(){
ReferenceCountGC objA = new ReferenceCountGC();
ReferenceCountGC objB = new ReferenceCountGC();
objA.instance = objB;
objB.instance = objA;
objA = null;
objB = null;
System.gc();
}
}
GC Roots
通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为“引用链”,当一个对象到GC Roots没有任何引用链相连,也就是从GC Roots到这个对象不可达时,证明此对象不可用。
GC Roots的对象:
虚拟机栈的栈帧中的局部变量表中引用的对象。
方法区中类静态属性引用的对象。方法区中常量引用的对象。
本地方法栈中JNI(Java Native Interface)引用的对象。
引用
- 强引用:“Object obj = new Object();”垃圾收集器不会回收强引用。
- 软引用:在将要发生OutOfMemoryError时,会把这些对象进行第二次回收。
- 弱引用:被弱引用关联的对象只能生存到下一次垃圾收集发生之前。
- 虚引用:在这个对象被回收时收到一个系统通知。
回收方法区
永久代主要回收废弃常量和无用的类。
只要没有任何一个对象引用这个常量,这个常量就会被清理出常量池。
一个类需要满足3个条件才算无用的类:
- 堆中不存在该类的实例
- 该类的ClassLoader已经被回收
- 该类的java.lang.class对象没有在任何地方被引用,无法通过反射访问该类的方法。
垃圾收集算法
标记-清除算法
1.标记出所有需要回收的对象
2.标记完成后统一回收掉所有被标记的对象
缺点:
1.效率不高,标记和清除的效率都不高
2.空间问题,留下大量不连续的内存碎片,如果需要大内存分配无法找到连续的大内存,提前触发垃圾收集
复制算法
将可用内存分为一块较大的eden空间和两块较小的survivor空间,每次使用其中的一块eden和其中一块survivor。当回收时,就将还存活的对象复制到另外一块survivor上面,然后把已使用的内存空间一次清理掉
当survivor空间不够用时,需要进行分配担保机制进入老年代
空间分配担保
在发生Minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则改为直接进行一次Full GC。如果小于,查看设置是否允许担保失败;如果允许,那只会进行一次Minor GC;如果不允许,也要进行一次Full GC。如果出现担保失败,会重新发起一次Full GC
标记-整理算法
标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清除掉边界以外的内存。
java堆的分配
新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2,
即:
新生代 ( Young ) = 1/3 的堆空间大小。
老年代 ( Old ) = 2/3 的堆空间大小。
其中,
新生代 ( Young ) 被细分为 Eden 和 两个 Survivor 区域,
这两个 Survivor 区域分别被命名为 from 和 to,以示区分。
Eden : from : to = 8 : 1 : 1 ,
即:
Eden = 8/10 的新生代空间大小,
from = to = 1/10 的新生代空间大小。
JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块 Survivor 区域是空闲着的。
分代收集
发生在新生代中的垃圾收集动作,所采用的是复制算法。
当对象在 Eden出生后,在经过一次 Minor GC 后,如果对象还存活,并且能够被另外一块 Survivor 区域所容纳,则使用复制算法将这些仍然还存活的对象复制到另外一块 Survivor 区域中,然后清理所使用过的 Eden 以及 Survivor 区域,并且将这些对象的年龄设置为1,以后对象在 Survivor 区每熬过一次 Minor GC,就将对象的年龄 + 1,当对象的年龄达到某个值时,这些对象就会成为老年代。
对于一些较大的对象 ( 即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代。
发生在老年代的垃圾收集动作,所采用的是标记-清除算法。