判断对象需要回收:1.引用计数法:给对象加上一个计数器,当有一个地方引用它,
计数器+1,引用失效时,计数器-1,当计数器为0时,判定该对象可回收
此方法无法检测循环引用 导致内存泄漏
//循环引用 public class MyObject{ public MyObject chlid; } public class Main{ public static void main(String[] args){ MyObject o1 = new MyObject(); MyObject o2 = new MyObject(); o1.child = o2; o2.child = o1; } }
2.可达性算法:指通过称为GC-Roots的对象为起始点,从这些结点向下搜索,
当从GCRoots到这个对象不可达时,被判定为可收回的对象
可作为GC ROOTs:栈中引用对象,方法区中静态属性和常量引用对象
finalize()方法: 当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。
四大引用:强:普遍存在,引用在就不回收引用对象
软:softReference,有用非必须,内存溢出前回收
String str = new String("aaa");//强引用 SoftReference<String> softRef = new SoftReference<String>(str);//软引用
弱:weakReference,非必须,下一次GC一定回收
虚:phantomRenference,不能取得对象实例,为了回收时收到系统通知而设置
回收方法区即永久代的回收:回收废弃常量(无对象引用)和
无用的类(所有实例化,类加载器被回收,反射无法访问)
回收算法:1.标记清除:先标记(可达对象)再清除,效率低,产生大量内存碎片,可能提前触发GC
2.复制:内存分成两块,用一块,之后把存活对象复制到另一块,再把这块清理;
回收新生代就是这个策略,但是具体分为3部分(8:1:1)
每次使用Eden和其中一块Survivor区。也就是说新生代可用内存为新生代内存空间的90%。
3.标记整理: 标记活的对象,让他们向一端移动,然后清理边界以外内存,用在老年代
4. 分代:堆分为新生代,用复制,老生代用标记整理 GC有两种方式 Minor GC(针对新生代),Eden空间不足触发 和 Full GC(针对新生代和老生代)1.老年代空间不足,2.Minor GC晋升到老年代的平均大小大于老年代剩余空间 3.System.gc() 会触发
stop the world: JVM由于要执行GC而停止了程序的执行 GC Roots可达性分析时,要使整个执行系统看起来像被冻结在某个节点,保证结果正确性
虚拟机采用OopMap的数据结构直接得知哪些地方存着对象引用
安全点:记录OopMap,程序中可安全进行GC的地方,选那些可让程序长时间执行的点,比如方法调用,循环,异常跳转
GC发生时让所有线程跑到安全点的方法:抢占式中断(不用),暂停线程,恢复不在安全点的线程,让它们跑到安全点。
主动式中断:线程均设一个标志,轮询发现为真就挂起自己,轮询标志的地方就是安全点
安全区域:引用关系不发生变化的区域,GC安全,“扩大的安全点”
垃圾收集器:CMS:基于标记清除(老年代),极大缩短停顿时间 初始标记--并发标记--重新标记--并发清除(清理垃圾对象 程序不会停顿)
G1: 分代收集,局部来讲基于复制,将堆划分多个区,跟踪每个区回收价值,维护优先列表 + 标记整理(减少碎片)
初始标记---并发标记---最终标记--晒选回收
其他:新生代的垃圾收集器有Serial(单线程)、
ParNew(Serial的多线程版本)
ParallelScavenge(吞吐量优先的垃圾收集器),
老年代有SerialOld(单线程老年代)、
ParallelOld(与ParallelScavenge搭配的多线程执行标记整理算法的老年代收集器)
对象分配策略:.1.对象优先在Eden区分配
2.大对象直接进入老年代
3.长期存活的进入老年代
4.Survivor区中相同年龄的所有对象大小的总和大于Survivor区空间的一半,
年龄大于或等于该年龄的对象直接进入老年代
空间担保分配:在发生MinorGC(回收年轻代)之前,HandlePromotionFailure允许担保失败,
老年代最大可用连续存储空间小于新生代所有对象总空间,且大于历次晋升到
老年代对象的平均大小,进行一次MinorGC,若不满足条件,改为FUllGC(堆及永久代)