文章目录
垃圾回收基础
- 什么是垃圾:内存中不在被使用到的内存空间就是垃圾。
引用计数法
在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。
- 优点:实现简单、效率高;
- 缺点:不能解决对象之间的循环引用。
可达性分析法(根搜索法)
通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”,如果某个对象到GC Roots间没有任何引用链相连,则证明此对象是不可能再被使用的。
-
能够作为GCroots的对象:
在虚拟机栈(栈帧局部变量)中引用的对象、方法区类静态属性的引用对象、方法区中常量引用的对象、本地方法栈中引用的对象。 -
具体实现上的优化
-
HotSpot中使用了OopMap的结构,保证准确快速完成GCroot的枚举。并且为了防止引用关系发生变化,设置了安全点,在安全点上进行记录和GC操作。到达安全点的方法也可以分为抢先式中断和主动式中断。抢先式式全部暂停,没有到达安全点的继续运行一下,这个方法几乎不被使用。主动式设置了标志位,在每个安全点出都查询标志位。并且还要检查Java堆的大小,确认是否有足够的内存分配资源。另外,存在安全区域,保证代码在这段区域中,引用关系不会变化。
-
记忆集:用于记录从非收集区域指向收集区域的指针集合的抽象数据结构。记录跨代引用的情况。具体实现,卡表法。
-
写屏障:维护卡表状态。在引用类型字段赋值前后,执行写屏障,更新卡表。
引用分类
强软弱虚
-
强引用:类似Object a = new A()无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回
收掉被引用的对象。 -
软引用:还有用但是并不必须。只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存才会抛出内存溢出异常。
-
弱引用:非必须对象,被弱引用关联的对象只能生存到下一次垃圾收集发生为止。当垃圾收集器开始工作,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
-
虚引用:一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知
判断垃圾的步骤
- 实例垃圾
- 根搜索算法判断不可用
- 看看是否有必要执行finalize方法,只有第一次被回收时执行。
- 两个步骤完成没人使用,属于垃圾。进行垃圾回收。
- 类垃圾(同时满足)
- JVM中该类的全部实例被回收
- 加载该类的CLassLoader被回收
- 没有任何地方引用该类的Class对象,无法在任何地方通过反射访问这个类
可以进行类的卸载。
GC类型
- Minor